Search code examples
flaskpostnginx-reverse-proxy

Nginx reverse proxy gives 405 not allowed when doing POST


without reverse proxying my flask server with nginx GET and POST are working fine. but in reverse proxy its not working.

my nginx.conf file is

# nginx.conf
# HTTP server block for handling HTTP requests

`server {
    listen 80;

    location / {
        proxy_pass http://flask:5000;
        proxy_http_version 1.1;
        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 Content-Type "application/json";
    }

}`

Error I faced is

$ curl -X POST -H "Content-Type: application/json" -d '{"message": "Hello from cURL!"}' http://x.x.x.x/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   184  100   153  100    31   2091    423 --:--:-- --:--:-- --:--:--  2555

<!doctype html>
<html lang=en>
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method is not allowed for the requested URL.</p>`

Solution

  • i have made changes to code file and configuration file, now nginx is reverse proxying correctly. app.py

    from flask import Flask, request, jsonify
    
    app = Flask(__name__)
    
    @app.route('/', methods=['GET', 'POST'])
    def save_payload_to_file():
        if request.method == 'POST':
            # Code to handle POST requests
            data = request.get_json()
            if data is not None:
                with open("response_data.txt", 'a') as f:
                    f.write(str(data) + "\n")
                return jsonify({"message": "Payload received and saved successfully."}), 200
            else:
                return jsonify({"error": "Invalid JSON data"}), 400
        else:
            # Code to handle GET requests
            return "Hello, Flask Server!"
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000)
    

    nginx.conf:

    worker_processes 1;
    events { worker_connections 1024; }
    
    http {
        sendfile on;
        server {
            listen 80;
            server_name ip_address;  # Replace with your domain name or IP address
    
            location / {
                proxy_pass http://flaskapp:5000;
            }
        }
    
        server {
            listen 443 ssl;
            server_name domain_name;  # Replace with your domain name or IP address
    
            ssl_certificate /etc/nginx/ssl/your_domain.crt;
            ssl_certificate_key /etc/nginx/ssl/keypair.pem;
    
            location / {
                proxy_pass http://flaskapp:5000;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
            }
        }
    }
    

    ignore second server bock in nginx.conf if you dont want ssl to be added

    docker-compose file

    version: '3'
    services:
      nginx:
        image: nginx:latest
        ports:
          - "80:80"
          - "443:443" #if ssl needed
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf:ro
          - ./your_domain.crt:/etc/nginx/ssl/your_domain.crt #if ssl needed
          - ./keypair.pem:/etc/nginx/ssl/keypair.pem #if ssl needed
        depends_on:
          - flaskapp
    
      flaskapp:
        build: .
        ports:
          - "5000:5000"
        volumes:
          - /home/flask:/app