Reputation: 5
I have two Symfony server instances. First is on 127.0.0.1:8080, second is on 127.0.0.1:8081.
When I'm trying to send POST method from the second instance to the first instance, using url 127.0.0.1:8081/create, I receive HTTP 500.
I'm using Windows 10. Running the servers locally works without a problem. The POST method works perfectly. So that's mean there is some problem with a Docker, but I don't know where. Is it CORS problem?
Here is my docker-compose.yml in the first instance:
version: '3'
services:
nginx:
build:
context: ./docker/nginx/
dockerfile: Dockerfile-nginx
volumes:
- .:/var/www/symfony/
ports:
- 8080:80
php:
build:
context: ./docker/php74/
dockerfile: Dockerfile-php74
volumes:
- .:/var/www/symfony/
and in the second instance:
version: '3'
services:
nginx:
build:
context: ./docker/nginx/
dockerfile: Dockerfile-nginx
volumes:
- .:/var/www/symfony/
ports:
- 8081:80
php:
build:
context: ./docker/php74/
dockerfile: Dockerfile-php74
volumes:
- .:/var/www/symfony/
Here is default.conf for the nginx:
server {
proxy_busy_buffers_size 512k;
proxy_buffers 4 512k;
proxy_buffer_size 256k;
listen 80;
server_name localhost;
root /var/www/symfony/public;
location / {
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /index.php/$1 last;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass php:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
# https://enable-cors.org/server_nginx.html
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
error_log /dev/stdout info;
access_log /var/log/nginx/symfony_access.log;
}
Has anyone had a similar problem before?
@EDIT: This is my ApiController.php where I'm making a call to other server instance.
<?php
namespace App\Controller;
use App\Entity\Argument;
use App\Repository\ArgumentRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class ApiController extends AbstractController
{
/**
* @Route("/create", name="create_argument", methods={"POST"})
*/
public function createArgument(Request $request, HttpClientInterface $client)
{
if (!strpos($request->headers->get('Content-Type'), 'application/json'))
{
$data = $request->toArray();
$name = $data['name'];
$response = $client->request(
'POST',
'http://127.0.0.1:8080/name',
[
'headers' => [
'Content-Type' => 'application/json',
],
'json' => ['name' => $name],
]);
if ($response->getStatusCode() == 200)
{
$content = $response->toArray();
$content['name'] = strrev($content['name']);
$argument = new Argument();
$argument->setName($content['name']);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($argument);
$entityManager->flush();
return new Response("Argument added", Response::HTTP_OK);
}
}
return new Response("Bad request", Response::HTTP_BAD_REQUEST);
}
/**
* @Route("/show", name="show_arguments", methods={"GET"})
*/
public function showArguments(ArgumentRepository $repository)
{
$arguments = $repository->findAll();
if (!$arguments)
return new Response('There are no tasks.', Response::HTTP_NOT_FOUND);
$encoders = [new XmlEncoder(), new JsonEncoder()];
$normalizers = [new ObjectNormalizer()];
$serializer = new Serializer($normalizers, $encoders);
$content = $serializer->serialize($arguments, 'json');
return new JsonResponse($content, Response::HTTP_CREATED, [], true);
}
}
Upvotes: 0
Views: 1189
Reputation: 1646
When you send the request to the http://127.0.0.1:8080/name
by Symfony HTTP client inside the container, the IP 127.0.0.1
is localhost of first php container, not your host with Windows.
The first server instance knows nothing about the second.
You should use the IP of your host machine with Windows instead 127.0.0.1
The example:
$response = $client->request(
'POST',
'http://10.0.75.1:8080/name',
[
'headers' => [
'Content-Type' => 'application/json',
],
'json' => ['name' => $name],
]
);
Also, you can merge 2 docker-compose.yml files into one, so you will have a common network between 2 server instances and each instance will know about other.
Updated:
Also, you can add hostname: hostname
for php service and use hostname
as URL of your host.
version: '3'
services:
nginx:
build:
context: ./docker/nginx/
dockerfile: Dockerfile-nginx
volumes:
- .:/var/www/symfony/
ports:
- 8081:80
php:
build:
context: ./docker/php74/
dockerfile: Dockerfile-php74
volumes:
- .:/var/www/symfony/
hostname: hostname
PHP code:
$response = $client->request(
'POST',
'http://hostname:8080/name',
[
'headers' => [
'Content-Type' => 'application/json',
],
'json' => ['name' => $name],
]
);
Upvotes: 1