'Socket.IO working locally, but not in Docker

SocketIO is working locally with flask run -8000 but when running in Docker I'm not able to pass messages with SocketIO. I've tried to make a simple app so you can reproduce what's happening:

app.py

import flask
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
import requests
from datetime import datetime
import logging
import time
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, logger=True, engineio_logger=True)

logging.getLogger('socketio').setLevel(logging.ERROR)
logging.getLogger('engineio').setLevel(logging.ERROR)
logging.getLogger('geventwebsocket.handler').setLevel(logging.ERROR)

@app.route('/')
def privacy():
    return render_template('index.html') # Product Page

@app.after_request
def add_header(r):
    """
    Add headers to both force latest IE rendering engine or Chrome Frame,
    and also to cache the rendered page for 10 minutes.
    """
    r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    r.headers["Pragma"] = "no-cache"
    r.headers["Expires"] = "0"
    r.headers['Cache-Control'] = 'public, max-age=0'
    return r

# Flask App

@socketio.on('hello')
def connected(message):
    data = message
    print('Message received from browser:', data)
    
    # Thanks I got your message
    emit('reply', {'data': 'Hello browser. I received your message.'})

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

index.html

<html>
<head>
    <title>Testing</title>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script type="text/javascript"
        src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.0/socket.io.slim.js"></script>
</head>
<body>
    <button id="button">Say hi to Flask</button>
    <p id=reply></p>
    <script>
        $(document).ready(function () {
            var socket = io.connect('http://' + document.domain + ':' + location.port);
            // Say hi to flask
            var btn = document.querySelector('#button')
            function addReply() {
                console.log('clicked it');
                socket.emit('hello', {
                    data: 'Hello Flask!'
                });
            }
            // Listen for the reply
            btn.addEventListener('click', addReply, false);
            socket.on('reply', function (msg) {
                // Successful connection message
                document.querySelector('#reply').innerText = msg.data
            });
        });
    </script>
</body>
</html>

Dockerfile:

FROM python:3.9
RUN mkdir /app

COPY ./src app/src
COPY ./requirements.txt app/requirements.txt

WORKDIR app/
RUN pip install -U pip setuptools\
    && pip install -r requirements.txt\
    pip install numpy 

WORKDIR ./src
CMD pip list
CMD exec gunicorn --bind :8000 --workers 1 --threads 8 app:app

requirements.txt

certifi==2021.10.8
chardet==3.0.4
click==7.1.2
DateTime==4.3
dnspython==2.2.0
eventlet==0.24.1
Flask==1.0.2
Flask-SocketIO==3.0.2
greenlet==1.1.2
gunicorn==20.0.4
idna==2.7
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
monotonic==1.6
python-dateutil==2.7.5
python-engineio==2.3.2
python-socketio==2.0.0
pytz==2021.3
requests==2.20.1
six==1.16.0
urllib3==1.24.3
Werkzeug==1.0.1
zope.interface==5.4.0

I'm seeing the error AttributeError: 'Response' object has no attribute 'status_code'

Is there something different I need to do when running in a docker container? I've been building the the command docker build -t hello . and publishing with docker run -t -i --publish 8000:8000 hello in case that's the cause of the issue.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source