My backend consists of a simple Symfony REST API, my frontend is a vue application. When I now try to call the API from my vue application with localhost:8080 or 127.0.0.1:8080, I get a Connection refused-error. When I try to call the API via my server’s public IP, I run into CORS issues.
Because I make those calls in an executed js file via axios, i’m not able to use the docker container names. Does anyone have an idea?
I assume you’re trying to use Nginx to serve both the Vue.js application and the Symfony API on port 8080, to avoid all CORS issues? We’ll need to see your Nginx configuration then.
I’d actually expect the Nginx container to run on standard ports, that is: 80 and 443. Apparently you’ve got some server in your Vue.js container running on port 8080, for which you can then remove the ports and add expose: 8080 to make that internal port available to other containers (but not to other non-Docker clients on the host). Same goes for Symfony, replace the ports with expose: 9000. Next, make Nginx use ports: 80:80 to allow the browser to connect to port 80, and make Nginx proxy some /api/* to http://php:9000/* and proxy everything else to http://client:8080/*.
First, thank you for your detailed reply. This already helped me a lot in terms of unterstanding. I adjusted the docker-compose.yml as you suggested and exposed the ports and removed the mappings. My default.conf looks like this:
Also, Nginx is probably logging errors in its log files.
When you replaced the ports of the first containers with expose, then those indeed will only be accessible through the Ningx container, which needs ports: 80:80 (using proper Yaml-syntax).
Right now, when I try the / route, I get an Invalid Host header and on the /api/ route I get a 502 Bad Gateway. The logs doesn’t offer any further information.
I think that this is not affected by server_name in Nginx, so I’d guess that is thrown by whatever server is in the Vue.js container, which may have been configured to, say, only allow the domain localhost, or 127.0.0.1? You could still define ports for that container to see if you could get the same error when accessing it directly, without Nginx as an intermediate proxy server?
For this I’d assume this is thrown by Nginx. So, something is off in your proxy_pass for /api/, I’d guess.
Also, make sure to peek in the logs of the Vue.js and Symfony servers.
…and, Nginx will be making requests for the host name client rather than, say, localhost. So you’ll need to relax the configuration of whatever server is running for Vue.js, or make Nginx set the HTTP Host header to something that this other server knows about (like localhost).
For even more complex mappings, you can use ~ to define a regular expression, along with (?<group-name> ...) to capture part of the match for later use:
Also, make sure to test with a full URL that actually works without Nginx. It’s not likely that just calling http://localhost/api/ without any further details in the REST path should return any results? You’ll likely need some http://localhost/api/some/path/a/b/c instead. (Assuming the Symfony REST API even supports HTTP GET.)
I have something like an “debug” route, which is api/user/login. This route just returns a json-object. Before we made those changes, I was able to reach it without any prefix. I’ve already tried it with /api/api/user/login, but it results in the same error.
I also tried to simply insert my old configuration for the /api/ route, which results in a File not found. But at this point I have no idea which path the php container is listenting to, to fix this.
As the PHP server seems to be getting the request and then closing the connection without any error, maybe it’s also expecting a different HTTP Host header?
I’d temporarily restore the ports mapping for the PHP container, to make that container accessible from your browser (but also leave the expose in place for Nginx), to ensure that the following works: http://localhost:9000/api/user/loginhttp://localhost:9002/api/user/login.
If that works, then I feel that the Nginx route using the default port 80 should work too, http://localhost/api/user/login, when using:
Yeah, originally I was invoking the php container via nginx. So every request send to the nginx container was send to the php container on port 9000. That’s why the php container has a volume with the symfony folder.
And it also did some mapping to index.php. I’d expect/want that mapping to be done in whatever server is running in the PHP container.
You mean the Nginx container, right? PHP is not my strong suit, but seeing fastcgi_pass php:9000 I’d very much expect this to be using the network, hence Nginx would not need access to the PHP files, hence would not need some volume mapping?
No, just in your browser. Given the ports: 9002:9000 mapping, the PHP container can be accessed by non-Docker clients. But given your earlier @rewriteapp and fastcgi_param in Nginx, I wonder if that PHP container can be used standalone…
I think your earlier Nginx configuration would map /some/path to index.php/some/path. So, maybe http://localhost:9002/index.php/user/login would work. That’s not nice, of course, but good to kow if that indeed works.
If that works, then one could probably use something like the following in Nginx. But I’d try to add that logic to the PHP container instead: