I've been working towards dockerizing our production environment, which consists of a React frontend which makes API calls to an Nginx server. The Nginx server reverse-proxies all the requests to an ASP .NET Core application. I've managed to get the backend images (.NET and database) working and communicating correctly via docker-compose, but now I'm trying to tie in Nginx and it isn't working correctly. My configuration is as follows:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events { worker_connections 1024; }

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    gzip on;

    # docker provides 'app' network address for api image
    upstream app_servers {
        server api:8080;

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        return 301 https://$host$request_uri;

    server {

        # SSL configuration
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;

        ssl_certificate /etc/nginx/server.crt;
        ssl_certificate_key /etc/nginx/server.key;

        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name localhost;

        location /ver {
            proxy_pass   http://app_servers/api/version;
            proxy_set_header Host $host;
        location / {
            if ($request_method = OPTIONS ) {
                add_header 'Access-Control-Allow-Origin' '*' always; 
                add_header Access-Control-Allow-Methods "POST, OPTIONS";
                add_header Access-Control-Allow-Headers "Accept, Cache-Control, x-csrf-token, Authorization, Content-Type";
                add_header Content-Length 0;
                add_header Content-Type text/plain;
                return 200;

            add_header 'Access-Control-Allow-Origin' '*' always;

            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;

            proxy_pass         http://app_servers/graphql;
            #proxy_redirect     off;

            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri $uri/ =404;

The only difference between this configuration and the production server is that in production the proxy_pass is targeting instead of app_servers, and the servername is an actual server name instead of localhost. The hostname api comes from the service definition in docker-compose.

What I'm experiencing is that I can successfully access the /ver endpoint, but any other request which should be routed to api:8080/graphql results in a 404. However, I can easily connect to the docker container exposing 8080 with GraphQL playground and make requests.

Any insight would be greatly appreciated, I'm not 100% confident this is specifically an Nginx issue but all evidence points that way.


It appears the solution was to remove the following lines:

try_files $uri $uri/ =404;
proxy_set_header   Host $host;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.