Background
I am setting up a local development environment that somewhat replicates a production server environment using NginX, MySQL, and Symfony/PHP-based web applications.
Codebase
I have set up a small public repository to replicate the issue, consisting of three containers: NginX
, App
, and API
.
https://gitlab.com/Extarion/docker-workshop
Intended Functionality
The API container has a single path /api/data
that returns a message containing the current date and time.
The App container performs a request to the API app via Symfony's HttpClient
, retrieving said message and showing it on a simple web page.
Primary Issue
Once the App container executes these lines of code, it returns a 500 error.
$response = $this->client->request('GET', 'http://API:9000/api/data');
$message = $response->getContent();
HTTP 500 Internal Server Error
Symfony\Component\HttpClient\Exception\TransportException
Recv failure: Connection reset by peer for "http://api:9000/api/data".
I am in the process of learning more about Docker, NginX, and the related configuration for my applications. What am I missing?
Troubleshooting So Far
I've attempted some suggestions found online, but I can't properly troubleshoot this problem not knowing what it relates to exactly.
- Requesting data from
http://api.local/api/data
directly works as expected. - Both requests to
api.local:9000
andAPI:9000
resolve to the same 500 error. - Tried changing
127.0.0.1:9000
to0.0.0.0:9000 in
/usr/local/etc/php-fpm.d/www.conf`. - Tried exposing the PHP ports via
docker-compose.yml
by addingexpose
for port9000
for both API and App containers. - No entries are added to
api-access.log
andapi-error.log
.
Docker Configuration
version: '3'
services:
server:
container_name: NginX
image: nginx:1.14.0
tty: true
ports:
- '80:80'
networks:
- local-network
volumes:
- .\nginx:/etc/nginx/conf.d
- .\api:/var/www/api
- .\app:/var/www/app
api:
container_name: API
image: php:8.1.3-fpm
tty: true
networks:
- local-network
volumes:
- .\api:/var/www/api
app:
container_name: App
image: php:8.1.3-fpm
tty: true
networks:
- local-network
volumes:
- .\app:/var/www/app
networks:
local-network:
driver: bridge
NginX Configuration
API
server {
server_name api.local;
index index.php;
root /var/www/api/public;
access_log /var/log/nginx/api-access.log;
error_log /var/log/nginx/api-error.log;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass API:9000;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
App
server {
server_name app.local;
index index.php;
root /var/www/app/public;
access_log /var/log/nginx/app-access.log;
error_log /var/log/nginx/app-error.log;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass App:9000;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
PHP Setup
API Route
class DataController extends AbstractController
{
/**
* @Route("/api/data")
*/
public function index(): Response
{
$today = new DateTime();
return $this->json('The date and time are currently ' . $today->format('Y-m-d H:i:s'));
}
}
App Route
class ExternalDataController extends AbstractController
{
private HttpClientInterface $client;
public function __construct(HttpClientInterface $client)
{
$this->client = $client;
}
/**
* @Route("/")
*/
public function index(): Response
{
// $response = $this->client->request('GET', 'http://API/api/data'); // Failed to connect to api port 80: Connection refused for "http://api/api/data".
$response = $this->client->request('GET', 'http://API:9000/api/data'); // Recv failure: Connection reset by peer for "http://api:9000/api/data".
$message = $response->getContent();
return $this->render('external_data/index.html.twig', [
'message' => $message,
]);
}
}