はじめに
Dockerコンテナを使って、PHP-FPMとNginxを連携させている際に、NginxからPHP-FPMにリクエストを送った際に「Connection reset by peer」エラーが発生しました。この記事では、この問題の原因と解決方法について、具体的な手順と設定例を交えながら解説します。
環境
- Docker:20.10.17
- Compose:v2.10.2
- PHP-FPM:8.3.1
- Nginx:1.24
- OS:Amazon Linux 2023(Dockerコンテナ内)
問題の概要
NginxコンテナからPHP-FPMコンテナにリクエストを送信した際、以下のエラーが発生しました。
curl web:9000
curl: (56) Recv failure: Connection reset by peer
また、Nginxのエラーログには次のようなエラーメッセージが記録されていました。
2024/09/18 13:12:48 [error] 7#7: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.30.0.1, server: localhost, request: "GET /test.php HTTP/1.1", upstream: "fastcgi://172.30.0.2:9000", host: "localhost:8080"
これは、NginxがPHP-FPMに接続できたものの、接続がリセットされた状態を示しています。
原因
/etc/php-fpm.d/www.conf
ファイルにあるlisten.allowed_clients
の設定が原因でした。この設定は、PHP-FPMが受け入れるクライアントのIPアドレスを制限するものです。デフォルトでは127.0.0.1
のみが許可されているため、nginx
コンテナ(別のIPアドレス)からの接続が拒否されていました。
listen.allowed_clients = 127.0.0.1
解決方法
listen.allowed_clients
の設定をコメントアウトすることで、すべてのクライアントからの接続を許可するように変更します。
1. www.conf
の設定変更
/etc/php-fpm.d/www.conf
を開き、以下の行をコメントアウトします。
; listen.allowed_clients = 127.0.0.1
2. PHP-FPMの再起動
設定変更後、PHP-FPMを再起動して設定を反映させます。
# PHP-fpmが動作しているwebコンテナを再ビルドして起動
docker compose up --build -d web
3. 動作確認
NginxコンテナからPHP-FPMコンテナに再度リクエストを送って、接続が正常に行えるか確認します。
# Nginxコンテナに入る
docker-compose exec nginx bash
# PHP-FPMにリクエスト
curl web:9000
設定全体の確認
以下は、設定全体を確認するための手順です。
Docker Compose 設定 (docker-compose.yml
)
version: '3.8'
services:
web:
build:
context: .
dockerfile: web/Dockerfile
volumes:
- ./src:/usr/share/nginx/html
- ./web/www.conf:/etc/php-fpm.d/www.conf
expose:
- "9000"
networks:
- app-network
nginx:
build:
context: .
dockerfile: nginx/Dockerfile
ports:
- '8443:443'
- '8080:80'
volumes:
- ./src:/usr/share/nginx/html:ro
depends_on:
- web
networks:
- app-network
networks:
app-network:
driver: bridge
PHP-FPM設定 (www.conf
)
[www]
listen = 0.0.0.0:9000
; listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 100
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
Nginx設定 (nginx.conf
)
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html/public;
index index.php index.html index.html;
# PHP-FPMの設定を追加
location ~ \.php$ {
fastcgi_pass web:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
server {
listen 443 ssl http2;
server_name localhost;
root /usr/share/nginx/html/public;
index index.php index.html index.html;
ssl_certificate "/etc/pki/nginx/server.crt";
ssl_certificate_key "/etc/pki/nginx/private/server.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
# PHP-FPMの設定を追加
location ~ \.php$ {
fastcgi_pass web:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
まとめ
NginxとPHP-FPMをDockerで連携させる際に発生する「Connection reset by peer」エラーは、PHP-FPMの設定に起因することが多いです。今回のケースでは、listen.allowed_clients
をコメントアウトすることで問題を解決しました。同様の問題に直面した場合は、PHP-FPMの設定ファイルを確認してみてください。