After configure the nginx, I can't see the index page - python

This is my first time to use nginx
I wrote a simple python/tornado code as the following, when I used python server.py I could see the index.html page.
from tornado.options import define, options
from db import MongoImpl
define("port", default=8000, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render("./pages/index.html")
app = tornado.web.Application([(r'/', IndexHandler)],
debug=True)
app.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
Then I started to configure the nginx.conf, I added the following to default nginx.conf:
http {
server{
listen 8000;
root /home/ubuntu/work/mytornado/pages;
index index.html index.htm;
}
then i nginx -s reload
however, when I used http://myipaddress, i only see the nginx welcome page, not my index html....
Is there anything wrong ?

You cannot run both nginx and your tornado server on port 8000. You need to give them each a different port, and configure nginx to proxy to tornado with a proxy_pass directive (this will replace the root directive you have here which serves pages from the filesystem. If you want nginx to serve some files from the filesystem and some from tornado then you'll need to use two location blocks).
A complete nginx configuration for use with tornado can be found in the docs: http://www.tornadoweb.org/en/stable/guide/running.html#running-behind-a-load-balancer

Related

How to Serve a Local App Using Waitress and Nginx

I have a dash(plotly) app set up using flask as the server and can serve it on our Windows Server to port:8041 using waitress. My code to launch waitress is below;
#!/usr/bin/env python3
from waitress import serve
from src.pacedash.app import server as application
if __name__ == "__main__":
serve(application, threads=100, port=8041)
Everything works great if I use python run_waitress.py, except that when someone on our network navigates to the servename:8041 there is a "Not Secure" warning next to the url. Our IT vendor was able to get a cert file and key, but I'm not sure how to bring those into my current setup.
I have been trying to use nginx, but I can't find a guide to setting it up with waitress and I'm not too familiar with web apps or wsgi because I primarily work as the lone data person here.
I have been working on this same issue and have a solution. The nginx .conf file needs have a location defined like this:
location /myapp/ {
# Define the location of the proxy server to send the request to
proxy_pass http://localhost:8041/myapp/;
# standard proxy_set_header stuff below...
}
Then in your Dash application set the url_base_pathname to the same value:
app = dash.Dash(__name__, url_base_pathname='/myapp/')
I would use ngrok to expose your web app. It's amazingly simple:
Read this: https://ngrok.com/
I could be misinterpreting what you need, because I am not familiar with waitress (why not serve the app locally just using flask?), but if you need to test the live app, ngrok is what you should use.

Flask SERVER_NAME setting best pratices

Since my app has background tasks, I use the Flask context. For the context to work, the Flask setting SERVER_NAME should be set.
When the SERVER_NAME is set the incoming requests are checked to match this value or the route isn't found. When placing an nginx (or other webserver in front), the SERVER_NAME should also include the port and the reverse proxy should handle the rewrite stuff, hiding the port number from the outside world (which it does).
For session cookies to work in modern browsers, the URL name passed by the proxy should be the same as the SERVER_NAME, otherwise the browser refuses to send the cookies. This can be solved by adding the official hostname in the /etc/hosts and setting it to 127.0.0.1.
There is one thing that I haven't figured out yet and it is the URL in the background tasks. url_for() is used with the _external option to generate URLs in the mail it sends out. But that URL includes the port, which is different from the 443 port used by my nginx instance.
Removing the port from the SERVER_NAME makes the stuff described in the first paragraph fail.
So what are my best options for handling the url_for in the mail. Create a separate config setting? Create my own url_for?
You should use url_for(location, _external=True)
or include proxy_params if you use nginx.

Running a Flask app on nginx

I don't know exactly what I am doing but I am experimenting with running Flask on nginx. I am boiling it down to the simple bit of code below. First I have a test app in Flask like this:
from flask import Flask, render_template
app = Flask(__name__, static_folder='client', template_folder='client/html')
def show_home_page():
return render_template("home.html")
#app.route('/')
def server():
return show_home_page()
if __name__ == '__main__':
app.run(threaded=True)
If I run python app.py I can go to http://localhost:5000 and see the "Hello World". Next I read that I need to run uwsgi but its not clear what params I need to pass to it. I tried different things like:
uwsgi -s /tmp/app.sock --manage-script-name --mount ./=app:app
I also noted that I need to set my nginx conf file to match, but I am stuck on that as well (I just get a welcome from nginx on port 5000) and it doesnt seem to link with my Flask app. I googled around a bit but nothing has clicked yet.
server {
listen 5000;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
You can use refer this for Flask with Nginx and uWSGI:
Python flask with Nginx and uWSGI

Authentication on NGINX aganist Tornado

well, I just setup NGINX and now its working.
As my BackEnd WebServer under NGINX I have Python Tornado running:
I only use NGINX for allow big uploads (large-sized), so one of my URL (for upload) is served on NGINX and the rest of URLs are served by Tornado.
I use Sessions provided by Tornado (running at http://localhost:8080/), and NGINX is running at http://localhost:8888/;
Well this is my nginx config file:
location /images/upload {
upload_pass /after_upload;
.....
.....
.....
}
location /after_upload {
proxy_pass http://localhost:8080/v1/upload/;
}
As you see, there aren't anything about authentication on NGINX.
URL for proxy_pass requiere a session valid (provided by Tornado)
This is scheme of the system is the following:
When users log in the system, system create a Tornado (tornado sessions) session in server and in user's Browser, so I need pass authentication to NGINX and continue this authentication process again in Tornado Service.
How I change NginX for authenticate against Tornado?
Thanks in advance
Well, Nginx works as a Proxy, therefore is not necessary make changes in Tornado or in your application. For my application I just add rewrites from NGINX urls towards Tornado urls. So this includes all traffic (auth, etc.) and all HTTP structures like if you were working in Tornado.
server {
listen 8888; ## listen for ipv4
server_name localhost;
access_log /var/log/nginx/localhost.access.log;
client_max_body_size 100000M;
location / {
#Real Location URL for Tornado.
proxy_pass http://localhost:8080/;
}
}
Key is proxy_pass , where every requests for 8888 port are passed to 8080 port in localhost.
Everything is passed to Tornado BackEnd from Nginx.

AWS - Running webservice - Cherrypy + Python

I have a linux box (Ubuntu 10.10 server edition) in ec2. I have written a web service using cherrypy framework. Let's say this is the code that I have written.
import sys
sys.path.insert(0,'cherrypy.zip')
import cherrypy
from cherrypy import expose
class Service:
#expose
def index(self):
return 'Hello World'
cherrypy.quickstart(Service())
I have copied this file, the cherrypy.zip file to /var/www in my ec2 instance. [I should inform that I created the www directory manually, as it wasn't there]. Then I ran
python webservice.py
and got the message
[01/Apr/2011:13:50:04] ENGINE Bus STARTED
However, when I try to run
(I have masked my public ip)
ec2-1**-2**-1**-**.ap-southeast-1.compute.amazonaws.com/
in my browser, I get connection failed. Can anyone tell me where I have gone wrong? or what I should do?
EDIT:
Okay, here is something interesting that I found. When I do
python webservice.py
I see
ENGINE Serving on 127.0.0.1:8080
Which means, the webservice will run only for the local machine. How do I make set the service 0.0.0.0 (that is, to serve any IP address?)
Hope this detail is sufficient for understanding the problem I'm facing. Help, please :)
EDIT 2:
Oh well, found the solution :-) Have to add this before cherrypy.quickstart() call
cherrypy.config.update({'server.socket_host': '0.0.0.0',
'server.socket_port': 80,
})
The cherrypy.quickstart function takes a config argument, which can be a dict, an open configuration file, or a path to a configuration file. I favor using a path to a configuration file because that minimizes the hardcoding of settings that you might prefer to control from a startup script.
In addition, since you control the server, you could configure a reverse proxy to route requests to the CherryPy application. This gives you quite a bit of flexibility. For example, if you wanted to, you could run multiple instances of the CherryPy application in parallel, each configured to listen on a different port.
Here's a sample configuration file for nginx, instructing it to forward requests to a single instance of your CherryPy application:
server
{
server_name your.hostname.com;
  location / {
    proxy_pass http://127.0.0.1:8080/;
  }
}
And here's a sample configuration file instructing nginx to load-balance across two instances of your application, which are listening on the loopback address at ports 33334 and 33335:
upstream myapps {
server 127.0.0.1:33334;
server 127.0.0.1:33335;
}
server {
server_name your.hostname.com;
location / {
proxy_pass http://myapps;
}
}

Categories

Resources