Search code examples
dockernginxflaskssl-certificateuwsgi

Nginx, uwsgi and flask app in Docker container generating [SSL: CERTIFICATE_VERIFY_FAILED]


I am in process of creating an app using the following stack:

  • Python 3.6 + Flask
  • uwsgi
  • Nginx

executing inside a Docker Container. This app in turn calls Jira API to gather and manipulate data. Most of the inbound to app are working fine. But, when the app tries to call Jira API, it is throwing the following error: [SSL: CERTIFICATE_VERIFY_FAILED]

I believe, this issue is occurring due to a presence of a self-signed certificate in the chain (which is not avoidable). I did import the certs into docker image and curl command worked fine (initially curl was also throwing the insecure warning).

Also, in order to isolate the issue, I switched off nginx and launched the app directly using uwsgi (uwsgi --socket 0.0.0.0:8080 --protocol=http -w [module]:[app]) and see the same error in uwsgi console.

Does this mean that I need to import the SSL certificate into uwsgi ? If so, how exactly to do that. I don't intend to make my app secure using own certificate or keys. This program works, if I purely run the flask app without any uwsgi, nginx and docker.

[edit] Adding Nginx config

server {
    listen 8080;
    location / {
        try_files $uri @app;
    }
    location @app {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/uwsgi.sock;
    }
    location /static {
        alias /app/static;
    }
    location = / {
        index /static/index.html;
    }
} 

uwsgi-directly invoking it using CLI for debugging

[Edit2] So I did some more troubleshooting:

  1. Created one simple script which is just calling the Jira url
  2. Ran the script in my local (mac os) using python3 [scriptname]. This worked fine and printed a 200 OK
  3. Copied the same file into my container and ran the same code.
  4. Got the same issue.
  5. Used the same URL with CURL and it got the response.

It seems that even though curl works fine, python itself is throwing the SSL error. So NOW the question may be, how to handle SSL error with python !?


Solution

  • I was finally able to resolve the issue. The issue was related to request call being made by the code. By default, the request calls have verify set to true. Also, request uses in-built certs for verification. In my case, since I was using custom certs, request was failing to validate the Jira site. In order to solve the issue, I created an ENV variable in docker file and pointed request to refer to my image's certs directory. Exact line

    ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/
    

    Do note, the custom certs should still need to be imported into docker image during build.