pythonflaskuwsgidockerpy

uwsgi with https getting socket option missing


I am running a Flask application on Docker with uwsgi. I have been running it for years now, but we need to add https to it. I know I can use an HAProxy and do ssl offloading, but in our current setup we cant do it this way, at least not right now. We need to do the SSL directly on the application. I have tried multiple options and I keep getting "The -s/--socket option is missing and stdin is not a socket." Not sure what else to try. The server is uWSGI==2.0.26. Please help. below is my uwsgi.ini file.

[uwsgi]

module = wsgi:app
master = true
processes = 5
enable-threads = true
single-interpreter = true

buffer-size = 32768

# protocol = http
# socket = 0.0.0.0:5000
# protocol = https
shared-socket = 0.0.0.0:5000
https = 0,/app/ssl/app_cert.crt,/app/ssl/app_cert.key

stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0

stderr_logfile = /dev/stdout
stderr_logfile_maxbytes = 0

chmod-socket = 660
vacuum = true

die-on-term = true

py-autoreload = 1

Solution

  • You can use the following example to run your flask application with uwsgi and docker.

    I will provide a minimal example and you can use it to expand to your needs.

    The uwsgi conf were extracted from docs.

    uwsgi.ini

    [uwsgi]
    shared-socket = 0.0.0.0:443
    https = =0,ssl/server.crt,ssl/server.key
    master = true
    module = app:app
    uid = uwsgi
    gid = uwsgi
    

    app.py

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route("/")
    def hello():
        return "Hello, World!"
    
    if __name__ == "__main__":
        app.run() 
    

    requirements.txt

    Flask
    uWSGI==2.0.26
    

    Dockerfile

    FROM python:3.10-slim
    
    RUN apt-get update && apt-get install -y \
        build-essential \
        gcc \
        libssl-dev \
        && apt-get clean \
        && rm -rf /var/lib/apt/lists/*
    
    RUN groupadd -r uwsgi && useradd -r -g uwsgi -m uwsgi
    
    WORKDIR /app
    
    COPY requirements.txt /app/
    
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY . /app/
    
    COPY ssl/ /app/ssl/
    
    RUN chown -R uwsgi:uwsgi /app
    
    EXPOSE 443
    
    USER uwsgi
    
    CMD ["uwsgi", "--ini", "uwsgi.ini"]
    
    

    Create an ssl directory and generate a self-signed cert.

    mkdir ssl
    openssl req -x509 \
      -newkey rsa:2048 \
      -keyout ssl/server.key \
      -out ssl/server.crt \
      -days 365 -nodes -subj "/CN=localhost"
    

    Now you should have this folder structure:

    .
    ├── app.py
    ├── Dockerfile
    ├── requirements.txt
    ├── ssl
    │   ├── server.crt
    │   └── server.key
    └── uwsgi.ini
    

    Now build and run:

    docker build -t flask-uwsgi-example .
    docker run --rm --name flask -p 443:443 flask-uwsgi-example
    

    And test with curl:

    $ curl -k https://localhost:443
    Hello, World!