unable to access .env files while running with uwsgi - python

I'm using smtplib to send simple emails for booking in a flask application I'm using google mail and have an app password as well as allowed less secure applications. I have the booking system running on my personal computer, but as soon as I port it over to the VPS it stops working, for an unknown reason other than the username and password are not accepted, but they are definitely correct, and it will run by itself but wont when run in wsgi and nginx.
Nginx config
server {
listen 80;
server_name example.com;
# return 301 https://$server_name$request_uri;
location / {
uwsgi_pass unix:/path/too/chatbot.sock;
include uwsgi_params;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;`
ssl_certificate /path/too/keys.pem;
ssl_certificate_key /path/too//primarykey.pem;
ssl_trusted_certificate /path/too//keys.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
#ssl_dhparam /path/to/dhparam;
# intermediate configuration
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# replace with the IP address of your resolver
resolver 8.8.8.8;
location / {
include uwsgi_params;
uwsgi_pass unix:/path/too/chatbot.sock;
}
}
UWSGI.ini file
[uwsgi]
module=wsgi:app
master = true
processes = 5
enable-threads = true
socket = chatbot.sock
chmod.socket = 666
vacuum = true
die-on-term = true
.env
DIALOGFLOW_PROJECT_ID=projectid
GOOGLE_APPLICATION_CREDENTIALS=Ajsonfile.json
RESTFUL_CREDENTIALS=restful_credentials.json
MAIL_USERNAME=example#gmail.com
MAIL_PASSWORD=apasswordforemailaddress
My current thinking is that wsgi or nginx are unable too find the file due to some sort of permissions issue but I've chown'ed all the related files, I'm getting the same issue with my google api key now too.
all the information is stored in a .env file which has the correct group access, along with all the other files running on the site already.
I don't know what would be helpful to post here other than I'm using nginx and wsgi to expose a flask application, some items are stored in a .env file that doesn't seem to be read.

To get them to load while running in WSGI you need to use dot-env package
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())

[uwsgi]
base = /var/www/html/poopbuddy-api
chdir = %(base)
app = app
I don't know exactly what chdir does but I think it at least sets the default location to the root directory of the app. From there, load_dotenv() works.

Related

Certbot + Nginx infinite redirect loop fix?

This is giving me an infinite redirect loop for some reason. Here is what I see on my console when I go to the website. I think it has to do with the final server block. It used to check if the host was equal to stringapi.net and then redirect you to https.
Any help would be appreciated!
From,
A confused 17 year old.
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
upstream stringapi {
server 127.0.0.1:8000;
}
server {
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name stringapi.net;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://stringapi.net;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/stringapi.net/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/stringapi.net/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
server {
listen 80;
server_name stringapi.net;
return 301 https://stringapi.net$request_uri;
}
I re-did the entire process (uninstalled and reinstalled NGINX) and then followed the guide for ec2 setup again and then configured certbot again and it worked.

First request doesnt terminate (no FIN) uWSGI + nginx

I am using nginx as a reverse proxy in front of a uWSGI server (flask apps).
Due to a memory leak, use --max-requests to reload workers after so many calls.
The issue is the following : When a worker just restarted/started, the first request it receives stays hanging between uWSGI and NGINX, the process time inside of the flask app is usual and very quick but the client waits until uwsgi_send_timeout is triggered.
Using tcpdump to see the request (nginx is XXX.14 and uWSGI is XXX.11) :
You can see in the time column that it hangs for 300 seconds (uwsgi_send_timeout) eventhough the HTTP request has been received by NGINX... uWSGI just doesn't send a [FIN] packet to signal that the connexion is closed. Then NGINX triggers the timeout and closes the session.
The end client receives a truncated response.. With a 200 status code. which is very frustrating.
This happens at every worker reload, only once, the first request no matter how big the request.
Does anyone have a workaround this issue? have I misconfigured something?
uwsgi.ini
[uwsgi]
# Get the location of the app
module = api:app
plugin = python3
socket = :8000
manage-script-name = true
mount = /=api:app
cache2 = name=xxx,items=1024
# Had to increase buffer-size because of big authentication requests.
buffer-size = 8192
## Workers management
# Number of workers
processes = $(UWSGI_PROCESSES)
master = true
# Number of requests managed by 1 worker before reloading (reload is time expensive)
max-requests = $(UWSGI_MAX_REQUESTS)
lazy-apps = true
single-interpreter = true
nginx-server.conf
server {
listen 443 ssl http2;
client_max_body_size 50M;
location #api {
include uwsgi_params;
uwsgi_pass api:8000;
uwsgi_read_timeout 300;
uwsgi_send_timeout 300;
}
For some weird reason, adding the parameter uwsgi_buffering off; in the nginx config fixed the issue.
I still don't understand why but for now this fixes my issue. If anyone has a valid explanation, don't hesitate.
server {
listen 443 ssl http2;
client_max_body_size 50M;
location #api {
include uwsgi_params;
uwsgi_pass api:8000;
uwsgi_buffering off;
uwsgi_read_timeout 300;
uwsgi_send_timeout 300;
}

Flask redirect appends get%20/%20HTTP/1.1)uri on production server. Working fine locally

I am trying to redirect all get requests to abc.example.com and send them to example.com. The following works on local:
#app.route('/', methods=['GET'])
def message_get():
return redirect('https://example.com')
But on production server, it fails. Instead of getting redirected, the url looks like this:
abc.example.comget%20/%20HTTP/1.1)uri
I observed that if I put in the whole url like this
https://abc.example.com
it redirects properly. but abc.example.com or http://abc.example.com fails.
I have a flask app with gunicorn app server. Nginx is used as reverse proxy. Unable to determine which of them is causing the problem. Guessing something to do with my nginx configuration. But any pointers will help. thanks.
Nginx configuration:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name abc.example.com;
return 301 https://$server_name$request)uri; }
server{
# SSL configuration
server_name abc.example.com;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-abc.example.com.conf;
include snippets/ssl-params.conf;
location / {
include proxy_params;
proxy_pass http://unix:/home/user1/apps/myapp/myapp.sock;
}
location ~ /.well-known {
allow all;
}
}
You have a typo in your first server section; it should be:
return 301 https://$server_name$request_uri;

Django on a url other than localhost [duplicate]

This question already has answers here:
How to specify which eth interface Django test server should listen on?
(3 answers)
Closed 7 years ago.
I have a server aerv.nl.
it has django (a python framework) but when i run the django server it says:
server started at: http://127.0.0.1:8000/ how can i let the server run on: http://www.aerv.nl/~filip/ ? (a real url)
You'll have to configure your http server and Django. For example if you're using apache you'll need to go through this:
https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/modwsgi/
What you're doing here is setting up your server to handle the http requests through your django app.
You will need to understand how DNS works, then use redirecting and then some proper server (like nginx or apache with e.g. gunicorn), not django development server, which shouldn't be used on production. There is no way you could do what you ask for just with ./manage runserver. All you can do is to change IP address and port to something different by e.g.: ./manage.py runserver 192.168.0.12:9999 so for example other computers in your network might access your site on this specific IP and port.
Example
You are owner of domain example.com, you have server where you want to server your site with IP address e.g. 5.130.2.19.
You need go to your domain provider and add an A record which connects these together: example.com -> 5.130.2.19.
Then on your server you set up webserver, e.g. nginx and let it run with e.g. this config for your particular server/site:
server {
listen 80;
server_name example.com;
client_max_body_size 4G;
location /static/ {
autoindex on;
alias /var/www/example/django/static/;
}
location /media/ {
autoindex on;
alias /var/www/example/django/media/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://upstream_server;
break;
}
}
upstream upstream_server {
server unix:/var/www/example/gunicorn.sock fail_timeout=10s;
}
then you would need to run gunicorn with something like
gunicorn example.wsgi:application --bind=unix:/var/www/example/gunicorn.sock
That should be all, but it's of course very brief. Just substitute example.com for your URL. It is up to you if this going to be specific record in nginx config (think about this as an entry point) or if it is going to be one of route specified in your django project.
How does it work?
User put example.com into an address bar, your computer then ask global DNS servers: To what IP address example.com points to?, DNS reply: It's 5.130.2.19. User's browser then sends HTTP request on that IP, where nginx get this request and looks inside its config if there is example.com handler. It find that it is there and that he should look for files in unix:/var/www/example/gunicorn.sock. He looks there and see working gunicorn, which basically parse python django project to something what nginx can present as your website.

Nginx not serving django image

I'm trying to follow the tutorial at http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html. I've gotten down to http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html#basic-nginx-test. Following the directions I have:
(env1)ubuntu#ip-172-31-28-196:~$ sudo /etc/init.d/nginx start
(env1)ubuntu#ip-172-31-28-196:~$ ls
host_type.py requirements.txt test.py tproxy
However when I go to my ubuntu ec2 instance at:
http://52.10.**.***:8000/media/media.jpg
The request times out. What am I doing wrong?
EDIT: - the config file
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name 52.**.***.**; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias ./media; # your Django project's media files - amend as required
}
location /static {
alias ./static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include ./uwsgi_params; # the uwsgi_params file you installed
}
}
nginx error log:
2015/03/03 18:06:06 [emerg] 1989#0: bind() to 0.0.0.0:80 failed (98: Address already in use)
2015/03/03 18:06:06 [emerg] 1989#0: bind() to [::]:80 failed (98: Address already in use)
2015/03/03 18:06:06 [emerg] 1989#0: still could not bind()

Categories