3

My Dockerfile is:


FROM ubuntu:18.04
RUN apt-get -y update
RUN apt-get install -y software-properties-common
RUN add-apt-repository ppa:deadsnakes/ppa
RUN apt-get update -y
RUN apt-get install -y python3.7 build-essential python3-pip
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8
RUN pip3 install pipenv
COPY . /app
WORKDIR /app
RUN pipenv install
EXPOSE 5000
CMD ["pipenv", "run", "python3", "application.py"]

When I do docker build -t flask-sample:latest ., it builds fine (I think).

I run it with docker run -d -p 5000:5000 flask-sample and it looks okay

But when I go to http://localhost:5000, nothing loads. What am I doing wrong?

Shamoon
  • 41,293
  • 91
  • 306
  • 570
  • 1
    One common cause is your Flask application listening on the container-private localhost address; you will see `Running on http://127.0.0.1:5000/` in the container logs, and if you see this you will not be able to reach the container from outside. [Deploying a minimal flask app in docker - server connection issues](https://stackoverflow.com/q/30323224/10008173) describes this in more detail. If that doesn't help, seeing the actual container logs and enough application source code to reproduce the issue would be useful. – David Maze Jul 08 '20 at 17:05

2 Answers2

4

Why do you need a virtual environment ? Why do you use Ubuntu as base layer:

A simpler approach would be:

Dockerfile:

FROM python:3
  
WORKDIR /usr/src/

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .


ENTRYPOINT FLASK_APP=/usr/src/app.py flask run --host=0.0.0.0

You put in your requirements.txt the desired packages (e.g flask). Build image: docker build -t dejdej/flasky:latest .

Start container: docker run -it -p 5000:5000 dejdej/flasky

If it is mandatory to use virtual environment , you can try it with venv:


FROM python:2.7

RUN virtualenv /YOURENV
RUN /YOURENV/bin/pip install flask

CMD ["/YOURENV/bin/python", "application.py"]
dejanualex
  • 3,872
  • 6
  • 22
  • 37
  • What does `-it` do? – Shamoon Jul 08 '20 at 15:06
  • -i = keep STDIN open even if not attached and -t = allocate a pseudo-tty it it's the opposite of -d (detach), it will be a little difficult to debug of you're running the container in backround (-d) – dejanualex Jul 08 '20 at 15:08
  • Should I use `ENTRYPOINT` or `CMD`? – Shamoon Jul 08 '20 at 15:13
  • 1
    Depends on what behaviour do you want to have , more exactly. `CMD` is an instruction that is best to use if you need a default command which users can EASILY override with `docker run` and `ENTRYPOINT ` if you want to define a container with a specific executable like python in this case , and afterwards if you want to override it you have to use entry-point flag e.g. `docker run -it --entrypoint /bin/bash IMAGE` – dejanualex Jul 08 '20 at 15:23
  • So given that my command won't change, I should probably use `ENTRYPOINT`? – Shamoon Jul 08 '20 at 15:24
1

Short answer: Your container is running pipenv, not your application. You need to fix the last line. CMD ["pipenv", "run", "python3", "application.py"] should be only CMD ["python3", "application.py"]

Right answer: I completely agree that there isn´t any reason to use pipenv. Better solution is replace your Dockfile to use a python image and forget pipenv. You already in a container, no reason to use a enviroment.

  • 1
    `pipenv run` is what runs my application with the right virtual environment – Shamoon Jul 08 '20 at 14:55
  • 1
    You dont need a virtual enviroment as you are running your app in a container docker. Why would you want to isolated a virtual enviroment if you are inside a isolated container? – Gustavo Barros Jul 08 '20 at 15:09
  • @GustavoBarros see here: https://github.com/pypa/pipenv/pull/2762#issue-209512016 – Dominic Aug 12 '21 at 08:19