0

I am trying to deploy a docker image on azure. I am able to create the docker image successfully, also deploy successfully. But I am not able to see anything on my URL I specified to create the deployment for container. My app is a python flask app which also uses dash.

I followed this azure tutorial from documentation. The example app works. But my app does not. I don't know how to debug this or where I am going wrong.

Dockerfile

FROM ubuntu:18.04

COPY . /app

WORKDIR /app

RUN apt update && \
    apt install -y make curl gcc g++ gfortran git patch wget unixodbc-dev vim-tiny build-essential \
    libssl-dev zlib1g-dev libncurses5-dev libncursesw5-dev libreadline-dev libsqlite3-dev \
    libgdbm-dev libdb5.3-dev libbz2-dev libexpat1-dev liblzma-dev libffi-dev && \
    apt install -y python3 python3-dev python3-pip python3-venv && \
    curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \
    curl https://packages.microsoft.com/config/ubuntu/18.04/prod.list > /etc/apt/sources.list.d/mssql-release.list && \
    apt update && \
    ACCEPT_EULA=Y apt-get -y install msodbcsql17 && \
    python3 -m venv spo_venv && \
    . spo_venv/bin/activate && \
    pip3 install --upgrade pip && \
    pip3 install wheel && \
    pip3 install -r requirements.txt && \
    cd / && \
    wget http://download.redis.io/releases/redis-5.0.5.tar.gz && \
    tar xzf redis-5.0.5.tar.gz && \
    cd redis-5.0.5 && \
    make && \
#    make test && \
    cd / && \
    rm redis-5.0.5.tar.gz && \
    cd / && \
    wget https://www.coin-or.org/download/source/Ipopt/Ipopt-3.12.13.tgz && \
    tar xvzf Ipopt-3.12.13.tgz && \
    cd Ipopt-3.12.13/ThirdParty/Blas/ && \
    ./get.Blas && \
    cd ../Lapack && \
    ./get.Lapack && \
    cd ../Mumps && \
    ./get.Mumps && \
    cd ../Metis && \
    ./get.Metis && \
    cd ../../ && \
    mkdir build && \
    cd build && \
    ../configure && \
    make -j 4 && \
    make install && \
    cd / && \
    rm Ipopt-3.12.13.tgz && \
    echo "export PATH=\"$PATH:/redis-5.0.5/src/\"" >> ~/.bashrc && \
   . ~/.bashrc

CMD ["./commands.sh"]

commands.sh

#!/bin/sh
. spo_venv/bin/activate
nohup redis-server > redislogs.log 2>&1 &
nohup celery worker -A task.celery -l info -P eventlet > celerylogs.log 2>&1 &
python app.py

Azure commands

sudo az acr login --name mynameregistry

sudo az acr show --name mynameregistry--query loginServer --output table

sudo docker tag spo_third_trial:v1 mynameregistry.azurecr.io/spo_third_trial:v1

sudo docker push mynameregistry.azurecr.io/spo_third_trial:v1

sudo az acr repository list --name mynameregistry--output table

sudo az acr repository show-tags --name mynameregistry--repository spo_third_trial --output table

sudo az acr show --name mynameregistry--query loginServer

sudo az container create --resource-group myResourceGroup --name spo-third-trial --image mynameregistry.azurecr.io/spo_third_trial:v1 --cpu 1 --memory 1 --registry-login-server mynameregistry.azurecr.io --registry-username mynameregistry --registry-password randomPassword --dns-name-label spo-third-trial --ports 80 8050

But when I go to http://spo-third-trial.eastus.azurecontainer.io I get this.

This site can’t be reached spo-third-trial.eastus.azurecontainer.io took too long to respond. Search Google for spo third trial eastus azure container io ERR_CONNECTION_TIMED_OUT

enter image description here

When I access logs with this command sudo az container logs --resource-group myResourceGroup --name spo-third-trial I get this

Running on http://127.0.0.1:8050/
Debugger PIN: 950-132-306
 * Serving Flask app "server" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
Running on http://127.0.0.1:8050/
Debugger PIN: 871-957-278

My curl output

 curl -v http://spo-third-trial.eastus.azurecontainer.io

* Rebuilt URL to: http://spo-third-trial.eastus.azurecontainer.io/
*   Trying <ip-address>...
* TCP_NODELAY set
* connect to <ip-address> port 80 failed: Connection timed out
* Failed to connect to spo-third-trial.eastus.azurecontainer.io port 80: Connection timed out
* Closing connection 0
curl: (7) Failed to connect to spo-third-trial.eastus.azurecontainer.io port 80: Connection timed out

I don't understand whether I am doing something wrong with creating docker, or with azure, or both. Would appreciate any help I can get.

NOTE: I am working on a virtual PC - AWS client, to access azure inside the client.

silent
  • 14,494
  • 4
  • 46
  • 86
  • I think you want to map the internal port 8050 to the external port 80. Put this is not possible, at least not how you specified it. `--ports 80 8050` means that you expose both ports, not that you map one to the other. Have you tried to call your app from a browser on http://spo-third-trial.eastus.azurecontainer.io:8050/ ? this might actually work – silent Aug 23 '19 at 16:50
  • See here: https://learn.microsoft.com/en-us/cli/azure/container?view=azure-cli-latest#az-container-create – silent Aug 23 '19 at 16:50
  • Mapping ports is not possible at the moment, but planned according to this: https://feedback.azure.com/forums/602224-azure-container-instances/suggestions/34082284-support-for-port-mapping – silent Aug 23 '19 at 16:52
  • @silent mapping ports is possible right? https://stackoverflow.com/a/48695897/5675288 says so. I checked the json(yml?) output after deployment, it shows `"ports": [ { "port": 80, "protocol": "TCP" }, { "port": 8050, "protocol": "TCP" } ],` – scientific_explorer Aug 23 '19 at 16:55
  • @silent I accessed with `...:8050` also. It gives the same error. – scientific_explorer Aug 23 '19 at 16:56
  • The link you referenced only means that you can expose multiple ports, not mapping them. You are exposing two ports right now – silent Aug 23 '19 at 17:00
  • Oh ok. Thank you for clarifying. I didn't know that. So is there any other alternative way of doing this? If you can suggest it would be really helpful. – scientific_explorer Aug 23 '19 at 17:11
  • Exposing it on port 8050 should generally work, since it looks like your Flask server is running fine. Not sure what the issue is. Maybe the flask is only serving requests from localhost, not from external clients?! You need to look into the documentation of your appserver there – silent Aug 23 '19 at 17:21
  • This worked when I tried it on my localhost with `--net=host` option for `docker run`. Maybe I'm missing something. For testing on localhost we used mysql (mysql on another computer), but on azure we use sql server. Will that change anything? I doubt, but would like a second opinion on that. – scientific_explorer Aug 23 '19 at 17:32
  • Your database should not matter at all (at least for now). You should still be able to at least connect to your frontend. Check your container instance in the Azure Portal to see if the ports are shown there and how the log looks – silent Aug 23 '19 at 17:35
  • @silent Thank you. Yes I checked the logs, both in CLI and in portal, it is the same as what I have posted in the question. Ports are shown as 80, 8050. – scientific_explorer Aug 23 '19 at 17:52
  • hm, hard to debug further from here then. I'd check the thing about maybe the flask server only accepting requests from localhost? but not sure if there is really an issue – silent Aug 23 '19 at 18:00
  • I have the flask app on the linux vm on azure. I am trying to access it externally, but so far no luck. Maybe some issue with the network security group (even though I have exposed port 8050, I can't `curl ...:8050`). Any suggestions on how I can see whether the app is accessible on the vm, via the vm itself? Maybe that's a test I can do to make sure that the app works on the VM. It definitely works on my local system. Apologies for asking so many questions - I don't have a senior dev guiding me at work, so... – scientific_explorer Aug 23 '19 at 18:05
  • you are on the VM and cannot use `curl` to access flask? then there might be something wrong with your flask there. On the VM itself the NSG has no effect – silent Aug 23 '19 at 18:09
  • The flask is inside the docker. I haven't tried testing the app directly on the VM. Good idea, I can try that also to debug. I tried `curl` on the docker image. It says `curl: (56) Recv failure: Connection reset by peer` – scientific_explorer Aug 23 '19 at 18:28
  • @silent I just tested on my vm. `curl` works for `http://127.0.0.1:8050` and gives correct html output but not for `http://localhost:8050` for my flask app. – scientific_explorer Aug 23 '19 at 20:01
  • Ok so then it really is only listening on „127.0.0.1“. It probably needs to listen on 0.0.0.0 – silent Aug 23 '19 at 20:23
  • I noticed that when i remove `server.config['SERVER_NAME']='127.0.0.1:8050'` from the `server.py` (i think `server.py` has the settings for the flask app), **and** have `app.run_server(debug=True, host='0.0.0.0', port='8050')` in my `app.py` - I am able to access the app from a browser when the flask app runs in my vm. This is good news I suppose... – scientific_explorer Aug 23 '19 at 20:36
  • @silent ok so it works on my vm. I tried the same thing with docker azure container, it didn't work - as predicted in the earlier comments. I guess this isn't a possible option then :( – scientific_explorer Aug 23 '19 at 21:02
  • hm weird. No idea what could be the issue. I dont see a reason why this shouldnt work in the same way in the Container Instance – silent Aug 23 '19 at 21:05
  • @silent ok my bad. Ssly my bad. I forgot to put the port number at the end. Now it works. So the issue **really** was the listening IP address part. – scientific_explorer Aug 23 '19 at 21:09
  • glad to hear it! I summarized the findings in an answer for other people to find – silent Aug 23 '19 at 21:12

1 Answers1

1

As discussed, a couple of points to your question:

  • I think you meant to map the internal port 8050 to the external port 80. But this is not possible currently (Aug-2019) in Azure Container Instances. There is an open item on Uservoice for this. --ports 80 8050 means that you expose both ports, not that you map one to the other.
  • The actual problem, as we found out, was that the python flask app was listening only on 127.0.0.1, not on 0.0.0.0. So it was not accepting requests from the outside.
silent
  • 14,494
  • 4
  • 46
  • 86
  • Thank you for your support and discussion. I didn't have anyone to brainstorm this with. Just one more question. Why not make `app.run_server(debug=True, host='0.0.0.0', port='80')` ? Will this not work for mapping just the port 80? – scientific_explorer Aug 23 '19 at 21:16
  • you can certain try. Yes, it should run it on port 80 - if the user is allowed to use the port. Often there can be a permission issue. but give it a try – silent Aug 23 '19 at 21:18
  • Ya I got permission denied. I think I can try manipulating some permissions and services. But is this recommended? Like, is it ok to run something on 80? Or is it better practice to run on some other port? – scientific_explorer Aug 23 '19 at 21:22
  • 1
    That’s a different topic and I’m sure there’s lots of material out there around it ;) – silent Aug 23 '19 at 21:46