Docker + uWSGI + NGINX + Swagger gives error: socket.error: [Errno 98] Address already in use

I know the error message socket.error: [Errno 98] Address already in use means that a port is already being used, but I cannot figure out why port 5000 is already being used.

I run into this error when running:

docker build -t mm-api .;
docker run -it 
  -e DB_HOST_IP=$DEFAULT_DB_HOST_IP 
  -e DB_HOST_USER=$DEFAULT_DB_HOST_USER 
  -e DB_HOST_PASS=$DEFAULT_DB_HOST_PASS 
  -e DB_HOST_SCHEMA=$DEFAULT_DB_HOST_SCHEMA 
  -p 0.0.0.0:5001:5000 mm-api;

This is the error I run into:

2019-05-21 21:28:37,804 CRIT uncaptured python exception, closing channel <POutputDispatcher at 139680364456560 for <Subprocess at 139680363965760 with name uwsgi in state RUNNING> (stdout)> (<type 'exceptions.IOError'>:[Errno 29] Illegal seek [/usr/lib/python2.7/dist-packages/supervisor/supervisord.py|runforever|227] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|handle_read_event|232] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|record_output|166] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|_log|142] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|info|275] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|log|293] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|emit|186] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|doRollover|211])
 * Serving Flask app "uwsgi_file_app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
2019-05-21 21:28:37,807 CRIT uncaptured python exception, closing channel <POutputDispatcher at 139680364456560 for <Subprocess at 139680363965760 with name uwsgi in state RUNNING> (stdout)> (<type 'exceptions.IOError'>:[Errno 29] Illegal seek [/usr/lib/python2.7/dist-packages/supervisor/supervisord.py|runforever|227] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|handle_read_event|232] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|record_output|166] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|_log|142] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|info|275] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|log|293] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|emit|186] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|doRollover|211])
Traceback (most recent call last):
  File "app.py", line 29, in <module>
    app.run(host='0.0.0.0', port=5000, debug=True)
  File "/usr/local/lib/python2.7/dist-packages/connexion/apps/flask_app.py", line 93, in run
2019-05-21 21:28:37,821 CRIT uncaptured python exception, closing channel <POutputDispatcher at 139680364014912 for <Subprocess at 139680363965760 with name uwsgi in state RUNNING> (stderr)> (<type 'exceptions.IOError'>:[Errno 29] Illegal seek [/usr/lib/python2.7/dist-packages/supervisor/supervisord.py|runforever|227] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|handle_read_event|232] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|record_output|166] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|_log|142] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|info|275] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|log|293] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|emit|186] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|doRollover|211])
    self.app.run(self.host, port=self.port, debug=self.debug, **options)
  File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 944, in run
2019-05-21 21:28:37,822 CRIT uncaptured python exception, closing channel <POutputDispatcher at 139680364014912 for <Subprocess at 139680363965760 with name uwsgi in state RUNNING> (stderr)> (<type 'exceptions.IOError'>:[Errno 29] Illegal seek [/usr/lib/python2.7/dist-packages/supervisor/supervisord.py|runforever|227] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|handle_read_event|232] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|record_output|166] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|_log|142] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|info|275] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|log|293] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|emit|186] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|doRollover|211])
    run_simple(host, port, self, **options)
  File "/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py", line 987, in run_simple
2019-05-21 21:28:37,823 CRIT uncaptured python exception, closing channel <POutputDispatcher at 139680364014912 for <Subprocess at 139680363965760 with name uwsgi in state RUNNING> (stderr)> (<type 'exceptions.IOError'>:[Errno 29] Illegal seek [/usr/lib/python2.7/dist-packages/supervisor/supervisord.py|runforever|227] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|handle_read_event|232] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|record_output|166] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|_log|142] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|info|275] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|log|293] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|emit|186] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|doRollover|211])
    2019-05-21 21:28:37,823 CRIT uncaptured python exception, closing channel <POutputDispatcher at 139680364014912 for <Subprocess at 139680363965760 with name uwsgi in state RUNNING> (stderr)> (<type 'exceptions.IOError'>:[Errno 29] Illegal seek [/usr/lib/python2.7/dist-packages/supervisor/supervisord.py|runforever|227] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|handle_read_event|232] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|record_output|166] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|_log|142] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|info|275] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|log|293] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|emit|186] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|doRollover|211])
s.bind(server_address)
  File "/usr/lib/python2.7/socket.py", line 228, in meth
2019-05-21 21:28:37,824 CRIT uncaptured python exception, closing channel <POutputDispatcher at 139680364014912 for <Subprocess at 139680363965760 with name uwsgi in state RUNNING> (stderr)> (<type 'exceptions.IOError'>:[Errno 29] Illegal seek [/usr/lib/python2.7/dist-packages/supervisor/supervisord.py|runforever|227] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|handle_read_event|232] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|record_output|166] [/usr/lib/python2.7/dist-packages/supervisor/dispatchers.py|_log|142] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|info|275] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|log|293] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|emit|186] [/usr/lib/python2.7/dist-packages/supervisor/loggers.py|doRollover|211])
    return getattr(self._sock,name)(*args)
socket.error: [Errno 98] Address already in use
unable to load app 0 (mountpoint='') (callable not found or import error)
*** no app loaded. going in full dynamic mode ***

Dockerfile:

FROM ubuntu:18.04

ARG APP_DIR="/opt/media-management/app"
ARG DB_HOST_IP
ARG DB_HOST_USER
ARG DB_HOST_PASS
ARG DB_HOST_SCHEMA
ARG DB_SERVICE_NAME
ARG AWS_ACCESS_KEY
ARG AWS_SECRET_KEY
ARG AWS_BUCKET_NAME
ARG IMAGE_BUCKET_NAME
ARG FTP_HOST_NAME
ARG FTP_USER_NAME
ARG FTP_PASSWORD
ARG IMAGE_SERVICE_HOST_NAME
ARG IMAGE_SERVICE_ROOT_PATH
ARG INGESTION_API_HOST_NAME
ARG NGINX_SERVICE_PORT="5000"

RUN apt-get update && apt-get -y upgrade
RUN apt-get install -y python-setuptools && apt-get install -y python-dev build-essential && apt-get install -y python-pip
RUN apt-get update --fix-missing && apt-get -y install unixodbc-dev && apt-get install -y imagemagick vim bpython nginx uwsgi uwsgi-plugin-python supervisor
RUN apt-get install -y build-essential libssl-dev libffi-dev python-dev
RUN apt-get install -y libxml2-dev libxslt1-dev python-dev
RUN pip install --upgrade pip && pip install awscli && pip install pyodbc & pip install cryptography
RUN pip install --upgrade setuptools
RUN apt-get install -y freetds-bin freetds-common freetds-dev libct4 libsybdb5
RUN apt-get install -y tdsodbc
RUN apt-get update

RUN mkdir -p $APP_DIR && 
    mkdir -p /mnt/downloads && 
    mkdir -p /mnt/logging

ADD requirements.txt $APP_DIR/
RUN pip install -r $APP_DIR/requirements.txt

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

# Copy all the application's source files to the container image
ADD . $APP_DIR

# Initialize all the needed environment variables
ENV DB_HOST_IP=$DB_HOST_IP
ENV DB_HOST_USER=$DB_HOST_USER
ENV DB_HOST_PASS=$DB_HOST_PASS
ENV DB_HOST_SCHEMA=$DB_HOST_SCHEMA
ENV DB_SERVICE_NAME=$DB_SERVICE_NAME
ENV AWS_ACCESS_KEY=$AWS_ACCESS_KEY
ENV AWS_SECRET_KEY=$AWS_SECRET_KEY
ENV AWS_BUCKET_NAME=$AWS_BUCKET_NAME
ENV IMAGE_BUCKET_NAME=$IMAGE_BUCKET_NAME
ENV FTP_HOST_NAME=$FTP_HOST_NAME
ENV FTP_USER_NAME=$FTP_USER_NAME
ENV FTP_PASSWORD=$FTP_PASSWORD
ENV IMAGE_SERVICE_HOST_NAME=$IMAGE_SERVICE_HOST_NAME
ENV IMAGE_SERVICE_ROOT_PATH=$IMAGE_SERVICE_ROOT_PATH
ENV INGESTION_API_HOST_NAME=$INGESTION_API_HOST_NAME
ENV NGINX_SERVICE_PORT="5000"
ENV APP_DIR=$APP_DIR
ENV CONFIG_DIR="$APP_DIR/config"

RUN ln -s /mnt/logging $APP_DIR/logging && 
    touch $APP_DIR/logging/media-management.log && 
    touch $APP_DIR/access.log && 
    touch $APP_DIR/errors.log

WORKDIR $APP_DIR

RUN chmod +x setup.sh templater.sh

ENV PYTHONPATH="${PYTHONPATH}:${APP_DIR}"

EXPOSE 5000

ENTRYPOINT ["/bin/bash", "-c", "./setup.sh; /usr/bin/supervisord -c $CONFIG_DIR/supervisord.conf"]

setup.sh:

#!/usr/bin/env bash

echo "Copying config files to expected locations...";
cp $CONFIG_DIR/freetds.conf /etc/freetds/;
cp $CONFIG_DIR/odbc.ini /etc/;
cp $CONFIG_DIR/nginx.conf /etc/nginx/conf.d/;
cp $CONFIG_DIR/supervisord.conf /etc/supervisor/conf.d/;

echo "Installing more config to the odbc.ini file...";
odbcinst -i -d -f $CONFIG_DIR/odbcinst.ini

freetds.conf:

# This file is installed by FreeTDS if no file by the same 
# name is found in the installation directory.  
#
# For information about the layout of this file and its settings, 
# see the freetds.conf manpage "man freetds.conf".  

# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
; tds version = 4.2
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
; dump file = /tmp/freetds.log
; debug flags = 0xffff

# Command and connection timeouts
timeout = 10
; connect timeout = 10

# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.  
# Try setting 'text size' to a more reasonable limit 
text size = 64512

# The basics for defining a DSN (Data Source Name)
# [data_source_name]
# #       host = <hostname or IP address>
# #       port = <port number to connect to - probably 1433>
# #       tds version = <TDS version to use - probably 8.0>
#
# # Define a connection to the Microsoft SQL Server
[MSSQL]
   host = {{DB_HOST_IP}}
   port = 1433
   tds version = 8.0
   AnsiNPW = YES
   QuotedID = YES

nginx.conf:

server {
    underscores_in_headers on;
    client_max_body_size 6000M;
    listen 0.0.0.0:5000;
    listen [::]:5000;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/uwsgi.sock;
        uwsgi_read_timeout 600s;
        uwsgi_send_timeout 600s;

        access_log {{APP_DIR}}/access.log;
        error_log {{APP_DIR}}/errors.log warn;
    }
}

odbc.ini:

# Define a connection to a Microsoft SQL server
# The Description can be whatever we want it to be.
# The Driver value must match what we have defined in /etc/odbcinst.ini
# The Database name must be the name of the database this connection will connect to.
# The ServerName is the name we defined in /etc/freetds/freetds.conf
# The TDS_Version should match what we defined in /etc/freetds/freetds.conf
[mssql]
Description             = MSSQL Server
Driver                  = FreeTDS
Database                = {{DB_HOST_SCHEMA}}
Server                  = {{DB_HOST_IP}}
Port                    = 1433
TDS_Version             = 8.0

odbcinst.ini:

[FreeTDS]
Description=FreeTDS Driver
Driver=/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup=/usr/lib/x86_64-linux-gnu/odbc/libtdsS.so

supervisord.conf:

[supervisord]
nodaemon=true

[program:uwsgi]
command=/usr/bin/uwsgi --ini {{CONFIG_DIR}}/uwsgi.ini
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=10000
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=10000

[program:nginx]
command=/usr/sbin/nginx 
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=10000
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=10000

uwsgi.ini:

[uwsgi]
socket = /tmp/uwsgi.sock
chown-socket = www-data:adm
chmod-socket = 664
cheaper-algo = spare
cheaper = 2
cheaper-initial = 4
workers = 8
cheaper-step = 1
callable = app
plugin = python
chdir=/opt/media-management/app
pythonpath=/opt/media-management/app
wsgi-file=app.py

app.py:

import os
import connexion
from flask_cors import CORS

app = connexion.App(__name__, specification_dir='./swagger/', debug=True)
app.add_api('swagger.yaml', arguments={'title': 'API Service'})

CORS(app.app)

if __name__ in ['__main__', 'uwsgi_file_app']:
    app.run(host='0.0.0.0', port=5000, debug=True)

I cannot understand why that port is already being used, but I suspect it has something to do with the way uWSGI is being setup. Please help, thank you!

Source: StackOverflow