This error occurs for me solely when using flask restplus with an nginx server. The server works correctly when just flask is used and the flask-restplus api works fine when running the app locally or even with:
uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:application
on my EC2 instance.
I have tried using gunicorn along side nginx (rather than uwsgi) but I get the same error in my /var/log/nginx/error.log file:
2017/07/03 20:30:02 [crit] 957#957: *1 connect() to unix:/home/jamie/my_app/my_app.sock failed
(2: No such file or directory) while connecting to upstream,
client: #.#.#.#, server: #.#.#.#, request: "GET /favicon.ico HTTP/1.1", upstream:
"uwsgi://unix:/home/jamie/my_app/my_app.sock:", host: "#.#.#.#", referrer: "http://#.#.#.#/"
The app is envoked through a wsgi.py that looks like this:
from main import application
if __name__ == "__main__":
application.run('0.0.0.0')
And the main.py file contains the following:
from boto3 import resource
from flask import json, request, abort
from flask import Flask
from flask_restplus import Api, Resource, fields
application = Flask(__name__)
api = Api(application)
#api.route('/users', methods=['GET', 'POST'])
class Users(Resource):
def get(self):
return users_get()
#api.expect(resource_fields)
def post(self):
return user_login()
#api.route('/users/<string:Username>', methods=['GET', 'PUT', 'DELETE'])
class User(Resource):
def get(self, Username):
return user_get(Username)
def put(self, Username):
return create_user(Username)
def delete(self, Username):
return delete_user(Username)
In order to configure the server I followed this digitalocean tutorial and my config is essentially the same. If anyone wants to see it I can provide it.
My uwsgi ini file is as follows:
[uwsgi]
module = wsgi:application
master = true
processes = 5
socket = my_app.sock
chmod-socket = 666
vacuum = true
die-on-term = true
My nginx sever config is at etc/nginx/sites-available/my_app
like so:
server {
listen 80;
server_name #.#.#.#;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/jamie/my_app/my_app.sock;
}
}
And finally my /etc/systemd/system/fitness_test_app.service file is like so:
[Unit]
Description=uWSGI instance to serve my_app
After=network.target
[Service]
User=jamie
Group=www-data
WorkingDirectory=/home/jamie/my_app
Environment="PATH=/home/jamie/my_app/myprojectenv/bin"
ExecStart=/home/jamie/my_app/myprojectenv/bin/uwsgi --ini my_app.ini
[Install]
WantedBy=multi-user.target
If anyone has any idea what could cause this problem an answer would be greatly appreciated as I have been unable to solve this issue for some time.
Related
I'm trying to implement a basic flask application in a docker container which uses ngnix container for request/response with the help of uWSGI module in python.
But, I'm running into a pid error which I'm totally confused of and banging my head. Please take a look to the files below
my flask application(run.py)
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "Welcome to the site"
if __name__ == "__main__":
app.run()
my app.ini file for uWSGI
[uwsgi]
wsgi-file = run.py
callable = app
socket = :8000
processes = 4
threads = 2
master = true
chmod-socket = 660
vacuum = true
die-on-term = true
my Ngnix conf file (default.conf)
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /sample {
include uwsgi_params;
uwsgi_pass flask:8000;
}
}
Note: flask is my container name and /sample is the page i want to reach which is flask ideally.
The error I run into while => curl http://localhost/sample
flask | [pid: 8|app: 0|req: 1/2] 172.23.0.1 () {32 vars in 343 bytes} [Tue Oct 4 03:00:29 2022] GET /thowbik => generated 207 bytes in 3 msecs (HTTP/1.1 404) 2 headers in 87 bytes (1 switches on core 0)
nginx | 172.23.0.1 - - [04/Oct/2022:03:00:29 +0000] "GET /sample HTTP/1.1" 404 207 "-" "curl/7.79.1" "-"
I checked all other setting, I hope, I did everything correct. While reaching / page it gives response nginx default page. but I cannot get response for /sample
For your Info https://www.youtube.com/watch?v=dVEjSmKFUVI, this is the tutorial I follow up to do.
Okay, I found the answer for the above question !!, the mount option in app.ini file should be declared as location. Like, mount = /sample=run.py and I get the response from flask
I try to wire Flask, gunicorn and nginx together but it ends up with 400 Bad request and 500 Errors.
Hope that anyone can help.
nginx conf
server {
listen 8000;
server_name 127.0.0.1;
location /Hello {
uwsgi_pass 127.0.0.1:8081;
}
}
wsgi.py snippet:
from app import app
app.run(host="127.0.0.1", port=8081)
app.py
app = Flask(__name__)
app.secret_key = "Not A Secret Anymore By Now"
#app.route('/Hello')
def hello():
return("Hello")
#if __name__ == "__main__":
# app.run(host='0.0.0.0', port=8000)
run cmd
export FLASK_APP=app
export FLASK_ENV=development
gunicorn --bind 0.0.0.0:8081 wsgi:app
test cases
curl http://localhost/ >>> returns nginx homepage
curl http://localhost/Hello >>> returns 404 Not found
curl http://localhost:8000/ >>> returns nginx homepage
curl http://localhost:8000/Hello >>> returns 502 Bad Gateway
curl http://localhost:8081 >>> return Connection refused
I try to get the test cases working, but have not clue why the errors appears, (nginx is restarted).
Thank you.
A few problems here...
Your view function ends without a return statement, which is probably the cause of the first 500 error. Better use:
#app.route('/Hello')
def hello():
print("Hello")
return 'success'
Also as you metntion uwsgi.py is emtpy, there's no app object to import there. Best point the gunicorn command at a valid app object:
gunicorn --bind 0.0.0.0:8081 app:app
Also the nginx location block expects the request to go to http://example.com/Hello/Hello. So better make the location block like the following. (Also ensure the port is the same one you provded to gunicorn's --bind flag).
location / {
proxy_pass http://127.0.0.1:8081;
}
Here I've also used proxy_pass as per the gunicorn deployment (with nginx) docs.
Now the request should work:
# Direct to app server...
curl -i http://localhost:8081/Hello
HTTP/1.1 200 OK
Server: gunicorn/20.0.4
# ...
success
and also:
# Via nginx:
curl -i http://localhost/Hello
HTTP/1.1 200 OK
Server: nginx
...
success
Beware that running gunicorn on all interfaces (0.0.0.0) means external requests could reach the app server directly (bypassing nginx) if no firewall is in place to prevent this. Might be worth instead binding gunicorn to the local interface: --bind 127.0.0.1:8081.
Also be careful in general, there's lots of ways to make security slip-ups when configuring stuff like this yourself. Good luck.
Hello all I was hoping I could receive some guidance on this matter.
I have a flask application that is setup on an ubuntu server. It uses ssh to create a tunnel to a Centos 7 Server that has it's mysql database. Upon running this application with python on the Ubuntu Server I'm able to perfectly login to my application and view data from database from domain ip. Now upon trying to run the application on nginx and uWSGI I can actually get to the login page from my domain name. But upon entering my credentials and trying to login, the page loads for around a minute and the I receive the 504 Connection Time Out Error
Would I be receiving this because my application is trying to reach out to another server while processing data from me. I'm not sure and nothing has been a help yet. Here are my files
server block
server {
listen 80;
server_name itinareport.tk www.itinareport.tk;
location / {
uwsgi_read_timeout 600;
include uwsgi_params;
uwsgi_pass unix:/home/pinchrep2/itinarep/itinarep.sock;
}
}
ini file
[uwsgi]
module = wsgi:app
master = true
processes = 5
socket = itinarep.sock
chmod-socket = 660
vacuum = true
die-on-term=true
wsgi.py
from main import app
if __name__ == "__main__":
app.run()
service file
[Unit]
Description=uWSGI instance to serve itinarep
After=network.target
[Service]
User=pinchrep2
Group=www-data
WorkingDirectory=/home/pinchrep2/itinarep
Environment="PATH=/home/pinchrep2/itinarep/it_venv/bin"
ExecStart=/home/pinchrep2/itinarep/it_venv/bin/uwsgi --ini itinarep.ini
[Install]
WantedBy=multi-user.target
Here is where I ssh from main py file
main.py
sshforward = SSHTunnelForwarder(
("public ip", 22),
ssh_username = 'user',
ssh_password = 'pass',
remote_bind_address = ('127.0.0.1', 3306)
)
sshforward.start()
local_port = sshforward.local_bind_port
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://root#localhost:{local_port}/asteriskcdrdb"
if __name__ == "__main__":
app.run(host='0.0.0.0')
Again I just need this to be deployed. Please point in the right direction configuration wise. I can get to application but as soon as logging in I receive this issue.
When your database connection url references "localhost", its really connecting via a unix socket.
You can connnect using a local_bind_address containing a unix socket adding ?unix_socket=/path/to/mysql.sock to the SQLALCHEMY_DATABASE_URI like this answer.
Seems connecting to a remote unix socket is waiting for this upstream issue to be implemented.
I am trying to follow this guid to deploy a flask server: https://medium.com/ymedialabs-innovation/deploy-flask-app-with-nginx-using-gunicorn-and-supervisor-d7a93aa07c18
I followed all the steps except the supervisor part which I fully skipped because the command wouldn't work, but it should not matter just to get things working.
When I run: sudo nginx -t
I get: nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)
What is teh issue? I have seen other people getting this error but the solutions don;t seem to work for me?
This is my nginx conf file:
server {
listen 80;
server_name <name>;
location / {
proxy_pass http://127.0.0.1:8000;
}
}
#
# A virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
And the python flask server:
from flask import Flask
from flask import render_template
from flask import send_file
app = Flask(__name__, static_url_path="/static", static_folder="/static")
app.static_folder = 'static'
#app.route("/")
def index():
return render_template("index.html")
#app.route("/uploads/resume")
def download_resume():
return send_file("static/documents/resume.pdf")
if __name__ == '__main__':
app.run(port=5010, debug=False, host='0.0.0.0')
Go to /etc/nginx/sites-available/default
Disable IPV6
I just commented out the following line
listen [::]:80 default_server ipv6only=on;
I have the following set up
src
|
|--flask_app
|--|--controllers.py
|--|--provider.py
|--|--__init__.py
|--config.py
|--wsgi.py
|--myproject.ini
|--myproject.sock
init.py creates the flask application
from flask import Flask, g
from flask_app.controllers import api_module
from flask_app.provider import CassandraDbProvider
# Define WSGI application object
app = Flask(__name__)
# Configure it
app.config.from_object('config')
cassandra = CassandraDbProvider(**app.config['DATABASE_CONNECT_OPTIONS'])
#app.before_request
def before_request():
g.db = cassandra
app.register_blueprint(api_module)
controler.py has the views that run on endpoints and also creates the blueprint
Finally wsgi.py has the following code
from cassandra_flask_app import app as application
if __name__ == "__main__":
application.run(host="0.0.0.0", port=5000)
myproject.ini
[uwsgi]
module = wsgi
logto = /var/log/uwsgi/uwsgi.log
threads = 10
socket = myproject.sock
chmod-socket = 664
vacum = true
die-on-term = true
Upstart script
description "uWSGI server instance configured to serve myproject"
start on runlevel [2345]
stop on runlevel [!2345]
setuid myuser
setgid www-data
env PATH=/home/myuser/myproject/myprojectenv/bin
chdir /home/myuser/myproject/src
exec uwsgi --ini myproject.ini
and nginx
server {
listen 80;
server_name myIpHere;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/myuser/myproject/src/myproject.sock;
}
}
controller.py
api_module = Blueprint('my_api', __name__, prefix='/api') # this might be wrong now because I don't have code infront of me
#myvmip/api/ works fine when uwsgi is master
#api_module.route('/', methods=['GET']):
def test_url():
return 'c'
#myvmip/api/normal_view/?query1=some_value" doesn't work when in master with no error. Only connection timeout error in nginx error.log.
#api_module.route('/nomral_view/', methods=['GET'])
def normal_view():
get_parameter = request.args.get('query1')
#uses g.db to connect to database and fetch some results
#database is cassandra db
return jsonify(**json)
It runs good on my developement machine. On my vm I load my flask application using nginx and uwsgi. I have set up uwsgi as described on many tutorial on the internet. The problem is that If I run uwsgi as master then It won't access some of my urls. Disabling it works properly. What do you think it could be? Does it matter uwsgi isn't loaded as master?
You need to add the following to your myproject.ini file
chdir = /path/to/project
callable = application
http://uwsgi-docs.readthedocs.org/en/latest/WSGIquickstart.html#deploying-flask
Also if you have a virtualenv you should add
venv=/path/to/venv