How to deploy SSL certificates on the Flask-based web app?

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. crt.sh | example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is: https://toxiverse.com

I ran this command:
First, I ran sudo certbot certonly --standalone -d www.toxiverse.com -d toxiverse.com and successfully get my SSL certificates;

And then $sudo -s scp /etc/letsencrypt/live/toxiverse.com/privkey.pem /root/ssl
$ sudo -s scp /etc/letsencrypt/live/toxiverse.com/fullchain.pem /root/ssl
$ sudo -s scp /etc/letsencrypt/live/toxiverse.com/cert.pem /root/ssl
$ sudo -s scp /etc/letsencrypt/live/toxiverse.com/chain.pem /root/ssl
Which copy the ssl certificates to the folder /root/ssl/

And then I copy local files to DigitalOcean and compose the containers: sudo docker compose -f docker-compose-do.yml up -d --build --force-recreate
The containers started successfully, but when I try to wget the website,it produced this output: Connecting to toxiverse.com (toxiverse.com)|192.241.131.84|:443... connected.
OpenSSL: error:0A00010B:SSL routines::wrong version number
Unable to establish SSL connection.

docker-compose.yml is:
version: '2'
services:
redis:
image: redis
volumes:
- ./redis:/usr/local/etc/redis

toxpro:
    build: .
    env_file:
        - docker-environment.env
    ports:
        - "443:5000"
    image: toxpro
    volumes:
        - ./instance/:/home/toxpro/instance
        - ./data/:/home/toxpro/data
        - ./root/ssl/fullchain.pem:/home/toxpro/fullchain.pem
        - ./root/ssl/privkey.pem:/home/toxpro/privkey.pem
    entrypoint: ["./boot.sh"]
    stdin_open: true
    tty: true

worker:
    build: .
    env_file:
        - docker-environment.env
    depends_on:
        - redis
        - toxpro
    entrypoint: ["./boot_worker.sh"]
    volumes:
        - ./instance/:/home/toxpro/instance
        - ./data/:/home/toxpro/data
        - ./root/ssl/fullchain.pem:/home/toxpro/fullchain.pem
        - ./root/ssl/privkey.pem:/home/toxpro/privkey.pem

volumes:
instance_vol:

And using dockerfile:
FROM python:3.8

RUN useradd toxpro

WORKDIR /home/toxpro

COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install -r requirements.txt

netcat is a program

necessary for troubleshooting

the networking

RUN apt-get update && apt-get install -y netcat-traditional

COPY app app
COPY ssl ssl
RUN pip install pyopenssl
RUN mkdir logs
RUN mkdir data
RUN mkdir instance # this is necessary for digital ocean

COPY boot.sh ./
RUN chmod +x boot.sh

COPY boot_worker.sh ./
RUN chmod +x boot_worker.sh

COPY boot_dashboard.sh ./
RUN chmod +x boot_dashboard.sh

RUN apt-get install libxrender1
ENV FLASK_APP app.py

RUN chown -R toxpro:toxpro ./
USER toxpro

EXPOSE 5000

My web server is (include version): gunicorn==20.1.0, Flask-based application

The operating system my web server runs on is (include version): Ubuntu 22.04.1 LTS

My hosting provider, if applicable, is: DigitalOcean

I can login to a root shell on my machine (yes or no, or I don't know): I don't know

I'm using a control panel to manage my site (no, or provide the name and version of the control panel):no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): 2.8.0

Hi @AnthonyTuzhu, and welcome to the LE community forum :slight_smile:

That usually means HTTPS and HTTP are "crisscrossed".
I see:

443 is HTTPS.
Does 5000 speak HTTP or HTTPS?
[you might need something more like "443:5001"]

2 Likes

You mean https and http are mixed together? I tried to get access to the website by http or https but neither of them work

I mean:

  • The router needs to forward HTTP connection request to an HTTP listener
  • The router needs to forward HTTPS connection request to an HTTPS listener

If port 5000 is NOT capable of doing HTTPS, then you CAN'T forward HTTPS connections to that port.

3 Likes

There is nothing forwarding port 80 to your docker image web service.

Where is the line for that?:
80:80

2 Likes

Flask is a web application framework, written in python, compatible with WSGI.

While Flask has a built-in server that can be used for development and testing purposes, it is not recommended to be used in production by the Flask development team. From their docs (their emphasis, not mine):

While lightweight and easy to use, Flask’s built-in server is not suitable for production as it doesn’t scale well. Some of the options available for properly running Flask in production are documented here.

Most people will run Flask on a WSGI container. Gunicorn and uWSGI are two of the most popular. Links to using them are on the official deployment docs: Deployment Options — Flask Documentation (1.1.x)

Generally speaking, a deployment will look like this:

  1. A gateway web server will speak to the public internet on port 80 and 443, and terminate the SSL connection on 443 (dropping it down to http for the backend and adding a private header). This could be a server like nginx or apache; it could also be a system like HAproxy.

  2. The gateway will forward the request to a backend server, which might be apache or nginx configured to handle wsgi via mod_wsgi (apache) or forwarding to a wsgi container server. Some deployments will feature both (the webserver will handle all requests, the wsgi ones will be sent to the appropriate container).

There are ways to handle SSL termination in flask for testing and development purposes, but most people prefer to use something like nginx to handle the SSL.

4 Likes

Whoops i linked to old docs. The new docs are Deploying to Production — Flask Documentation (3.0.x)

and the new warning is:

After developing your application, you’ll want to make it available publicly to other users. When you’re developing locally, you’re probably using the built-in development server, debugger, and reloader. These should not be used in production. Instead, you should use a dedicated WSGI server or hosting platform, some of which will be described here.

“Production” means “not development”, which applies whether you’re serving your application publicly to millions of users or privately / locally to a single user. Do not use the development server when deploying to production. It is intended for use only during local development. It is not designed to be particularly secure, stable, or efficient.

Again, the emphasis is from the developers of Flask.

4 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.