Can't manage to build and run a bottle.py app - python

I've been trying to setup a container to run an app with the bottle framework. Read everything I could find about it, but even so I can't do it. Here's what I did:
Dockerfile:
# Use an official Python runtime as a parent image
FROM python:2.7
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 8080
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
app.py:
import os
from bottle import route, run, template
#route('/<name>')
def index(name):
return template('<b>Hello {{name}}</b>!', name=name)
run(host='localhost', port=8080)
requirements.txt
bottle
By running the command docker build -t testapp I create the container.
Then by running the command docker run -p 8080:8080 testapp I get this terminal output:
Bottle v0.12.13 server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.
But when I go to localhost:8080/testing I get localhost refused connection.
Can anyone point me to the right direction?

Problem is this line:
run(host='localhost', port=8080)
It is exposing it for "localhost" insde the container you are running the code. You can use python library netifaces to get container external interface if you want to but I suggest you to set 0.0.0.0 as host like:
run(host='0.0.0.0', port=8080)
Then you will be able to access http://localhost:8080/ (asuming your docker engine is at localhost)
EDIT: mind your previous container might still be listening on 8080/tcp. Remove or stop previous container first.

Related

Docker executes python scripts only when I stopping the container

I'm trying to build a Docker image for my python app (a small api on aiohttp with a couple endpoints)
FROM python:3
WORKDIR /home/emil/Projects/elastic_simple_engine
COPY . .
RUN pip3 install -r requirements.txt
EXPOSE 5000/tcp
CMD ["python3", "entry.py"]
The last line of the Dockerfile runs a python script which starts aiohttp.web.Application():
# entry.py
# ...a few dozens of code lines above...
if __name__ == '__main__':
print('Initializing...')
aiohttp.web.run_app(app, host='127.0.0.1', port=5000)
After building an image I'm trying to run the container:
$ docker run -p 5000:5000 myapp
Docker runs the container silently without any output in shell but I can't reach my app's host: 127.0.0.1:5000 (everything works perfectly when I launch it without docker).
Only when I stop the container it prints in console the lines that should be shown during app's launch and shuts down:
Initializing...
======== Running on http://127.0.0.1:5000 ========
(Press CTRL+C to quit)
Please, help me figure out that I do wrong.
TLDR
Set host to 0.0.0.0
127.0.0.1 is the IP address to local interface. It can only communicate within the same host.
0.0.0.0 means a server (in this context) would listen to every available network interface (including 127.0.0.1).
Here, since you are not sharing the docker network, 127.0.0.1 is only available inside the container and not from outside the container. You should use 0.0.0.0 to access it from outside the container or pass --network="host" in docker run but this can have other complications with port sharing.

python3: can't find '__main__' module in 'app.py'

I'm trying to create a Docker container to be able to create a GUI with Flask for the utilisation of a tensorflow model.
The thing is that I would like to be able to modify my python files in real time and not have to rebuild my container everytime.
So for now I've created 3 files :
requirement.txt
Flask
tensorflow
keras
Dockerfile
# Use an official Python runtime as a parent image
FROM python:3.5.6-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python3", "app.py"]
app.py
from flask import Flask
import os
import socket
app = Flask(__name__)
#app.route("/")
def test():
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
So after all this I build my container with this command
docker build -t modelgui .
End then I use this command to run my container and make a link between the app file I want to modify on the host and the one in the container
docker run -p 4000:80 -v /home/Documents/modelGUI:/app modelgui
But I get this error and I really don't know why
/usr/local/bin/python3: can't find '__main__' module in 'app.py'
My problem might be dumb to resolve but I'm really stuck here.
Check that /home/Documents/modelGUI in your bind volume mount is the path to where your code files reside and that app.py in that path is not created as a directory rather than a python file with the code you intend to run.
If app.py in /home/Documents/modelGUI is a dir, then the cause of this problem is that are not calling your script app.py at all, you are just giving the Python interpreter a nonexistent script name, which in case a similarly named directory (case-insensitive actually) exists it tries to execute it.
I've tried to replicate:
$ ls -lFs
Dockerfile
app.py/
requirements.txt
Then called the Python interpreter with app.py:
$ python3 app.py
/usr/local/bin/python3: can't find '__main__' module in 'app.py'
Running this locally, it looks like mounting your volume is overwriting your directory:
No volume
docker run -it test_image bash
root#c3870b9845c3:/app# ls
Dockerfile app.py requirements.txt
root#c3870b9845c3:/app# python app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
With volume
docker run -it -v ~/Barings_VSTS/modelGUI:/app test_image bash
root#f6349f899079:/app# ls
somefile.txt
root#f6349f899079:/app#
That could be part of the issue. If you want to mount a filesystem in, I would mount it into a different directory. The default volume behavior is such that whatever you copied into app will be overwritten by the contents of modelGUI

Docker connection refused on all ports except 5000

I have just started with Docker. I have installed Docker Toolbox for Windows. I was trying out a sample Flask app to understand how things work. But I am stuck!. I am trying to access my app like this http://docker-machine-ip : port number but every time I do, I get '{docker-machine ip} refused to connect.'
I get no exceptions during the building and deploying stages. I also did docker ps to see that container is running. I even tried to access it via Kitematic but still no luck. Below are details related to the app
app.py
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Flask inside Docker shakel!!"
if __name__ == "__main__":
app.run(debug=True,host='0.0.0.0')
requirements.txt
flask
Dockerfile
FROM python:2.7
MAINTAINER Shekhar Gulati "shekhargulati84#gmail.com"
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["app.py"]
The docker commands I used for building and running are:
docker-machine ip default //To get docker machine ip
docker build -t flask-app .
docker run -d -p 6000:6000 flask-app
I have Windows 7 64 bit. Please let me know if any more info is required.
P.S. However I noticed that if I map my container to 5000 port it will run fine but on any other port I get connection refused
I don't know what am I missing here. This is my first attempt at Docker and I have googled for 4 hrs to find a solution but nothing is working. So it might be a very dumb mistake I am doing somewhere :).anyhow any help is very much appreciated. Thanks in advance.
That's because you didn't set the port for your flask application, which is port 5000 by default.
From flask documentation:
port – the port of the webserver. Defaults to 5000 or the port defined in the SERVER_NAME config variable if present.

Can't acces swagger server into docker container

I have a swagger server api in python that I can run on my pc and easily access to the user interface via web. I'm now trying to run this API into a docker container and place it into a remote server. After the doing the 'docker run' command int the remote server all seems to be working fine but when I try to connect I got a ERR_CONNECTION_REFUSED response. The funny thing is that if I enter into the container the swagger server is working and answer my requests.
Here is my Dockerfile:
FROM python:3
MAINTAINER Me
ADD . /myprojectdir
WORKDIR /myprojectdir
RUN pip install -r requirements.txt
RUN ["/bin/bash", "-c", "chmod 777 {start.sh,stop.sh,restart.sh,test.sh}"]
Here are my commands to build/run:
sudo docker build -t mycontainer .
sudo docker run -d -p 33788:80 mycontainer ./start.sh
Here is the start.sh script:
#!/bin/bash
echo $'\r' >> log/server_log_`date +%Y%m`.dat
python3 -m swagger_server >> log/server_log_`date +%Y%m`.dat 2>&1
And the main.py of the swagger server:
#!/usr/bin/env python3
import connexion
from .encoder import JSONEncoder
if __name__ == '__main__':
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = JSONEncoder
app.add_api('swagger.yaml', arguments={'title': 'A title'})
app.run(port=80, threaded=True, debug=False)
Does anyone know why I can't acces to 'myremoteserver:33788/myservice/ui' and what to change for solving it.
Thanks in advance
I finally managed to find out the solution. It's needed to tell the flask server of connexion to run on 0.0.0.0 so that not only local connections are allowed and to change in the swagger.yaml the url with the name of the server where the docker container is located
app.run(port=80, threaded=True, debug=False, host='0.0.0.0')

Unable to connect to server when running docker django container

I have looked through the questions on this site, but I have not been able to fix this problem.
I created and ran an image of my django app, but when I try to view the app from the browser, the page does not load (can't establish a connection to the server)
I am using docker toolbox, I am using OS X El Capitan and the Macbook is from 2009.
The container IP is: 192.168.99.100
The django project root is called "Web app" and is the directory containing manage.py. My Dockerfile and my requirements.txt files are in this directory.
My dockerfile is:
FROM python:3.5
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
My requirements.txt has django and mysqlclient
My django app uses Mysql, and I tried to view the dockerized django app in the browser with and without linking it to the standard mysql image. In both cases, I only see the following error:
problem loading page couldn't establish connection to server
When I did try linking the django container to the mysql container I used:
docker run --link mysqlapp:mysql -d app
Where mysqlapp is my mysql image and 'app' is my django image.
In my django settings.py, the allowed hosts are:
ALLOWED_HOSTS: ['localhost', '127.0.0.1', '0.0.0.0', '192.168.99.100']
Again, the image is successfully created when I used docker build, and it is successfully run as a container. Why is the page not loading in the browser?
I suggest to use yml file and docker compose. Below is a template to get you started:
[Dockerfile]
FROM python:2.7
RUN pip install Django
RUN mkdir /code
WORKDIR /code
COPY code/ /code/
where your files are located in code directory.
[docker-compose.yml]
version: '2'
services:
db:
image: mysql
web0:
build: .
command: python manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
depends_on:
- db
There might be a problem with your working directory path defined in Dockerfile. Hope above helps.
Solution provided by salehinejad seems to be good enough ,although i have not tested it personally but if you do not want to use yml file and want to go your way then you should expose the port by adding
-p 0:8000
in your run command
So your should look like this :
docker run -p 0:8000 --link mysqlapp:mysql -d app
I suspect you have not told Docker to talk to your VM, and that your containers are running on your host machine (if you can access at localhost, this is the issue).
Please see this post for resolution:
Connect to docker container using IP

Categories