gonginxbackend

Reverse Proxy to Golang backend not working (nginx)


Been working on a small web app and wanted to try out nginx, and Golang for my backend. Pretty new to Golang as this is my first Golang web project. Anyway, I'm having a problem with reverse proxying for my HTML login page:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="loginStyle.css">
  <title>Cosmic Cloud Login</title>
</head>

<body>

  <div class="loginContainer">
    <h1 class="headerText">Login</h1>
    <p>Please enter your login information</p>
    <form action="/login" method="POST">
      <div class="inputGroup">
        <label for="Username">Username</label>
        <input type="Username" id="Username" name="Username" placeholder="Enter your username" required>
      </div>

      <div class="inputGroup">
        <label for="Password">Password</label>
        <input type="Password" id="Password" name="Password" placeholder="Enter your password" required>
      </div>
      <button type="submit" class="loginButton">Login</button>
    </form>


  </div>

</body>

</html>

The nginx.conf file is as follows:

   server {
          listen 80;
   location / {
          root /var/www/html;
          index index.html;
   }

   location /login {
          proxy_pass http://0.0.0.0:8080;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
   }
   }

and the Go file is as follows:

package main 


import (
    "fmt"
    "net/http"
)



var validUsername = "test"
var validPassword = "test1234"

func loginHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
        http.Error(w, "Invalid Request method", http.StatusMethodNotAllowed)
        return 
    }

    username := r.FormValue("Username")
    password := r.FormValue("Password")

    if username == validUsername && password == validPassword {
        fmt.Fprint(w, "Login Successfull!")
    } else {
        http.Error(w, "Invalid Username or Password", http.StatusUnauthorized)

    }
}

func main() {
    http.HandleFunc("/login", loginHandler)
    fmt.Println("Server is running on :8080")
    http.ListenAndServe(":8080", nil)
} 

When sending a post request, the golang backend never receives it unless you specify port 8080. (e.g. "http://IP/login" does not work) ("http://IP:8080/login" does work) I've tried both in the local machine and on another machine on the network. TLDR: nginx isn't properly sending the POST request from the nginx web server (port 80) to the port where the Golang backend is listening on (port 8080). Any help is greatly appreciated, TYIA!

Edit: Also it's probably not a firewall issue since I disabled ufw in the testing environment.


Solution

  • It seems there was an issue with the proxy_pass IP because 0.0.0.0 is nonroutable IPV4 address.
    Also I created a GitHub repository to examplify the setup using the container name (go_app) in the proxy_pass and it worked fine.
    https://github.com/sullyvannunes/goland-nginx-repository

    nginx.conf

    events {}
    
    http {
        server {
            listen 80;
    
            location /login {
                proxy_pass http://go_app:8080/login;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
            }
       }
    }
    

    main.go

    func main() {
        http.HandleFunc("POST /login", func(w http.ResponseWriter, r *http.Request) {
            log.Println(r.URL)
            log.Println(r.Method)
    
            w.WriteHeader(http.StatusCreated)
            w.Write([]byte("Executado com sucesso"))
        })
    
        log.Println("Running on port 8080")
        http.ListenAndServe(":8080", nil)
    }