Search code examples
pythondockerflaskhttpslets-encrypt

Flask application on Docker with Let's Encrypt


I want to create a Flask application in a Docker instance that has HTTPS enabled using the Let's Encrypt method of obtaining an SSL Cert. The cert also needs to be auto-renewed every so often (3 months I think), which is already done on my server but the Flask app needs to get access to the file also!

What would I need to modify on this Docker file to enable Let's encrypt?

FROM ubuntu:latest
RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install -y python-pip python-dev build-essential
RUN pip install --upgrade pip
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["web/app.py"]

Solution

  • You can use the docker volume feature:

    A volume is a mount directory between the host machine and the container.

    There is two ways to create a volume with docker:

    1. You can declare a VOLUME command in the dockerfile

      FROM ubuntu:latest
      RUN apt-get update -y && apt-get upgrade -y
      RUN apt-get install -y python-pip python-dev build-essential
      RUN pip install --upgrade pip
      COPY . /app
      WORKDIR /app
      RUN pip install -r requirements.txt
      VOLUME /certdir
      ENTRYPOINT ["python"]
      CMD ["web/app.py"]
      

    This will create a directory named after the container id inside /var/lib/docker/volumes.

    This solution is more useful when you want to share something from the container to the host but is not very practical when it's the other way around.

    1. You can use the -v flag on docker create or docker run to add a volume to the container:

      docker run -v /certdir ./certdir web/app.py

    Where /certdir is the directory /certdir inside the container and ./certdir is the one on the host inside your project directory.

    This solution will work since the host directory will be mounted inside the container at the defined location. But without specifying it clearly in some documentation or provide a easy to use alias for your docker run/create command other user will not know how to define it.

    PS:quick tip:

    Put your RUN commands inside one single statement:

    ```
    FROM ubuntu:latest
    RUN apt-get update -y && apt-get upgrade -y \
        && apt-get install -y python-pip python-dev build-essential \
        && pip install --upgrade pip
    COPY . /app
    ```
    

    The advantage is docker will create only one layer for the installation of dependencies instead of three. (see documentation)