0

I'm facing an issue using Nestjs with an request coming from proxy_pass by nginx with docker-compose.

I have a nestjs service that listen on the port 3000 with the following endpoints

  • get /api/users/:id
  • get /api/users
  • post /api/users

I have the following nginx configuration

events {
   worker_connections 1024;
}
http {

    upstream ticketing_users {
        server ticketing_users:3000;
    }

    server {
        listen 80;
        server_name ticketing.dev;

        location ~ ^/api/users(.*)$ {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            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_intercept_errors on;
            proxy_pass http://ticketing_users/;
        }

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

Here is my nginx config in docker-compose.yaml :

reverse-proxy:
    image: nginx
    volumes:
      - ./docker/nginx.conf:/etc/nginx/nginx.conf
      - ./docker/nginx:/var/logs/nginx
    networks:
      - ticketing.dev
    ports:
      - 8080:80
    depends_on:
      - ticketing_users
    links:
      - ticketing_users

Here is my main.ts :

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(UsersModule, {
    cors: true,
    logger: ['verbose', 'debug', 'error', 'warn']
  });
  app.set('trust proxy', true);
  app.use(morgan('combined'));
  app.setGlobalPrefix('api');
  await app.listen(3000);
}
bootstrap();

and my controller (generated with cli so it's declared in the module) :

@Controller('users')
export class UsersController {
  @Get(':id')
  public findById(@Param('id') id: string): string {
    return id;
  }
}

And i've set ticketing.dev in my host file. But when i'm querying for exemple get http://ticketing.dev:8080/api/users/1234 with postman i always get the same result, i tried to put some console.logs but nothing appears :

{ "statusCode": 404, "message": "Cannot GET /api/users/1234", "error": "Not Found" }

But morgan middleware handle correctly the request and is showing :

GET /api/users/test 404 0.496 ms - 77

What am i doing wrong ?

3
  • Have you tried proxy_pass http://ticketing_users;? Commented Dec 19, 2022 at 23:11
  • Yes but my service ticketing_users is listening on port 3000, actually i have created a new project from stratch and copy pasted all the code and it works on the new repo (maybe some cache somewhere) i've tried docker-compose rm --all & docker-compose build --no-cache & docker-compose up --force-recreate on the old one but nothing... Commented Dec 20, 2022 at 8:09
  • Do you start ticketing_users:3000 also with docker compose? It should be in the same network. You can check connectivity by accessing the nginx container and pinging ticketing_users. Commented Dec 17, 2024 at 13:10

3 Answers 3

0
+150

I think I found the problem - it's in your nginx location configuration. The issue is with how the proxy_pass URL is handling the path rewriting.

The current configuration:

location ~ ^/api/users(.*)$ {
    proxy_pass http://ticketing_users/;
}

When you add a trailing slash to proxy_pass, nginx strips the matched location path. This means your /api/users/1234 request is being rewritten to just /1234, but your NestJS app expects /api/users/1234.

Here are two ways to fix this:

  1. Remove the trailing slash in proxy_pass:
location ~ ^/api/users(.*)$ {
    proxy_pass http://ticketing_users$1;
}
  1. Or, if you want to keep the trailing slash, modify your location block:
location ~ ^/api/users(.*)$ {
    proxy_pass http://ticketing_users/api/users$1;
}

Either solution will ensure the full path /api/users/1234 reaches your NestJS application.

Also, make sure your docker-compose networks are properly configured. Add this to your ticketing_users service:

networks:
  - ticketing.dev

To debug similar issues in the future, you can add these to your nginx config to see exactly what's being passed:

add_header X-Original-URI $request_uri;
add_header X-Proxy-Pass-URI $uri;

Let me know if it works!

Sign up to request clarification or add additional context in comments.

1 Comment

This helped my situation, I needed my NGINX proxy manager on the same docker network.
0

I don't really remember why (it's been a long time since) but here is how I was able to fix out my issue:

events {
   worker_connections 1024;
}
http {

    upstream ticketing_users {
        server ticketing_users:3000;
    }

    server {
        listen 80;
        server_name ticketing.dev;

        location ~ ^/api/users(\/.*)?$ {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            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://users_server/api/users$1;
        }

        underscores_in_headers on;
        proxy_intercept_errors on;
        access_log /var/logs/nginx/access_log access;
        error_log  /var/logs/nginx/error.log error;
    }
}

Comments

0

proxy_pass http://ticketing_users$1 /api/users/1234 networks:

  • ticketing.dev

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.