Docker Community Forums

Share and learn in the Docker community.

Calling another container results in Connection refused

I never thought I’d say it today, but it works. :heart_eyes:

This is the default.conf:

server {
listen       80;
server_name  localhost;
root /var/www/public;

location ~ /api/(?<target>.+) {
    fastcgi_pass php:9000;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    fastcgi_param PATH_INFO $target;
    fastcgi_param HTTPS off;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
}

location / {
    proxy_pass http://client:8080/;
    proxy_set_header Host localhost;
}

error_log /var/log/nginx/symfony_error.log;
access_log /var/log/nginx/symfony_access.log;
}

My frontend is reachable via the empty route, and my REST API is reachable via the /api/ route.

So with this setup, I should be able to call the api from the frontend via the localhost/api/ route?

1 Like

I’d say so, yes. So, both the frontend and Symfony are available on the very same protocol (HTTP), host and port (80), hence no CORS issues to be expected at all. In fact, I’d not include the localhost part when calling the API, but just use /api for which the browser will use the same protocol, host and port as the calling Vue.js application. So, the same thing will then work from, say, 127.0.0.1 or any true domain name.

Though things work, there’s still a tight mapping between Nginx and the PHP container, like for root /var/www/public (which I guess is how Nginx determines a value for $document_root), and for the mapping to index.php. You may want to look into that some day.

Also, you can remove any ports setting for the PHP container, as that is now only accessed through/by Nginx.

Aside, during development you can make the Vue.js development server proxy /api for you as well; see preingest-frontend/vue.config.js at main · noord-hollandsarchief/preingest-frontend · GitHub

It’s just like you’ve said. I can call the API from the frontend with just /api/user/login. I thank you really much, you’ve helped me a lot. I learned a lot.

The only thing which makes some trouble is, that Vue won’t connect to the WebSocket.

Could it be that the current configuration doesn’t allow the communication to this certain direction?

Is that just the WebSocket for the development server? Or a WebSocket for Symfony? I’ve no idea how to set up the latter. For non-FastCGI it would be something like:

location /sockjs-node/ {
    proxy_pass http://my-node-server:9000/sockjs-node/
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
}

Better examples in WebSocket proxying.

The problem was in my frontend. But your suggestion fixed it:

location /sockjs-node/ {
  proxy_pass http://client:8080/sockjs-node/
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header Host $host;
}

I think I get the point. I can just redirect every route to the related container.

I thank you very much. I feel much more confident now working with nginx and so on.

Actually, to make that work, the Symfony container would need to map /some/request/path to /some/server/document-root/index.php/some/request/path, which is now done by Nginx. So, yet another reason to make that container smart enough to do its own mappings. :slight_smile:

1 Like

I’m actually very happy I have a running project. I think I’ll never change ANYTHING in the setup. :joy:

Oh, as we’ve seen that the Vue.js container needs this to be localhost, the above will bite you if you ever access Nginx using something else than localhost, in which case $host will be set to whatever is used then. So, you’d better hardcode proxy_set_header Host localhost; for the WebSocket configuration too.

1 Like

ServiceA’s HTTP requests were being redirected (HTTP 307 status code) to https://serviceb:44359/api/bar being :44359 the host port for HTTPS. Host ports are not accessible between containers, container ports do. So if I access to serviceA’s terminal and send an HTTP request with curl verbose -v following redirections -L to the URI http://serviceb/api/bar I got the Connection Refused error:

root@serviceA_id:/app# curl -v -L http://serviceb/api/bar

  • Trying 10.168.0.3…
  • TCP_NODELAY set
  • Connected to serviceb (10.168.0.3) port 80 (#0)

GET /api/bar HTTP/1.1
Host: serviceb
User-Agent: curl/7.52.1
Accept: /

< HTTP/1.1 307 Temporary Redirect
< Date: Wed, 19 Jun 2019 08:48:33 GMT
< Server: Kestrel
< Content-Length: 0
< Location: https://serviceb:44359/api/bar
<

  • Curl_http_done: called premature == 0
  • Connection #0 to host serviceb left intact
  • Issue another request to this URL: ‘https://serviceb:44359/api/bar
  • Trying 10.168.0.3…
  • TCP_NODELAY set
  • connect to 10.168.0.3 port 44359 failed: Connection refused
  • Failed to connect to serviceb port 44359: Connection refused
  • Closing connection 1
    curl: (7) Failed to connect to serviceb port 44359: Connection refused
    Why I were being redirected to host port?

In Startup.cs my services were using app.UseHttpsRedirection();, that line was causing the problem.

The default configuration of HttpsPolicyBuilderExtensions.UseHttpsRedirection(IApplicationBuilder) method redirects to HTTPS host port by default. If you want to use a different port for redirection you need to add that option so Startup.cs will look like this:

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {

        ...

        services.AddHttpsRedirection(options =>
        {
            options.HttpsPort = 443;
        });

        ...

    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {

        ...

        app.UseHttpsRedirection();

        ...

    }
}