NGINX load balancer and flask application container - CORS and SocketIO

18 Views Asked by At

I would happy if you would be able to assist.

The Architecture is that there is a nginx container that serve as load-balancer container as listen on port 80.

and 4 Flask applications that are listen on port 5050.

I'm using Mozila firefox web browser (It also happen in Chrome).

This is my HTML file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Support automation</title>
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
      crossorigin="anonymous"
    />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.3.2/socket.io.js"></script>

    <link
      rel="stylesheet"
      type="text/css"
      href="{{ url_for('static', filename='style.css') }}"
    />
    <script src="{{ url_for('static', filename='script.js') }}"></script>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg bg-body-tertiary">
      <div class="container-fluid">
        <a class="navbar-brand" href="#">Download-Machines</a>
        <button
          class="navbar-toggler"
          type="button"
          data-bs-toggle="collapse"
          data-bs-target="#navbarNav"
          aria-controls="navbarNav"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Features</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Not-Decided-Yet</a>
            </li>
            <li class="nav-item">
              <a class="nav-link disabled" aria-disabled="true">Yaml-Merge</a>
            </li>
          </ul>
        </div>
      </div>
    </nav>
    <h1>Europe - Work Automation</h1>
    <script
      src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
      crossorigin="anonymous"
    ></script>
    <div class="button-container">
      {% for user in list_users %}
      <div>
        <span>{{user}} - </span>
        <button onclick="buttonClicked('script_test')">{{user}}</button>
      </div>
      {% endfor %}
    </div>
    <div class="output-container" id="output-container">
      <!-- Output will be displayed here -->
    </div>
  </body>
</html>

And this is my app.py Flask application:

from flask import Flask, render_template, send_from_directory, redirect, url_for, session, request, flash
from flask_socketio import SocketIO
from script_test import script_test
import sys
import os
from flask_cors import CORS
from datetime import timedelta

sys.path.append('./script_test.py')

app = Flask(__name__, static_folder='templates/static')

app.secret_key = "hello"
app.permanent_session_lifetime = timedelta(days=7)

# CORS(app, resources={r"/*": {"origins": "*"}})
cors = CORS(app,resources={r"/*":{"origins":"*"}})
socketio = SocketIO(app, cors_allowed_origins="*")


@socketio.on('button_clicked')
def handle_button_click(name):
    script_path = "script_test.py"
    if os.path.exists(script_path):
        output = script_test()  
        socketio.emit('output', output)
    else: 
        socketio.emit('Output','Error: Script not found')

@app.route('/static/<path:filename>')
def serve_static(filename):
    return send_from_directory('static', filename)

@app.route('/')
def hello():
    return render_template('index.html', list_users = ["User","User", "User", "User", "User", "User"])

@app.route('/yaml-merge')
def yaml_merge():
    return render_template('yaml-merge.html')

@app.route('/login', methods=["POST", "GET"])
def login():
    if request.method == "POST":
        session.permanent = True
        user = request.form["nm"]
        session["user"] = user
        return redirect(url_for("user"))
    else:
        if "user" in session:
            return redirect(url_for("user"))
        return render_template('login.html')

@app.route('/user')
def user():
    if "user" in session:
        user = session["user"]
        return f"<h1>{user}</h1>"
    else:
        return redirect(url_for("login"))

@app.route('/logout')
def logout():
    session.pop("user", None)
    flash("You have been logged out!", "info")
    return redirect(url_for("login"))


if __name__ == '__main__':
    socketio.run(app,debug=True, host='0.0.0.0', port=5050, allow_unsafe_werkzeug=True)

if i run the python app.py, I can access the Flask application in the chrome or mozila successfully and when i click on one of the users buttons everything work as expected.

when I containerize everything, the localhost:5050 is not responding but the nginx on port 80 it show me the web page but when i click on one of the users button it is not working, so I open up the consol log and so the error message bellow:

I get the error message: "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5050/socket.io/?EIO=4&transport=polling&t=OsyIc0R. (Reason: CORS request did not succeed). Status code: (null)."

I'm expecting that when i containerize everything, nginx will keep work as load-balancer listen on port 80 and 4 Flask application will listen on port 5050. and when I will browse to port 80 the buttons in the web page will work.

0

There are 0 best solutions below