I am using this tutorial - part 1, but i am not sure how to test if the app is running with nginx serving static files or not.
I have exactly the same code.
/etc/nginx/sites-available/flask_project
server {
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static {
alias /home/www/flask_project/static/;
}
}
And then:
gunicorn app:app -b localhost:8000
All routes are working fine. However if I do http://localhost:8000/static i will see
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
And apparently I should see the page with <h1>Test!</h1> from static folder.
What i am doing wrong?
Basically i want to know how configure nginx to serve static files and then confirm.
-app.py
-static
-index.html
First, requests to port 8000 completely bypass nginx, so nothing strange here. You should go to localhost without port number.
Second, you have to symlink this config to /etc/nginx/sites-enabled and reload nginx.
Third, your static location is wrong. You have location without trailing slash and alias with one. They should always be with or without trailing slash simultaneously. And in this case it's even better to have root directive.
server {
root /home/www/flask_project;
index index.html;
location / {
proxy_pass http://localhost:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static/ {
# empty. Will serve static files from ROOT/static.
}
}
You should make request directly http://localhost:8000/static/index.html then you will see response.
But if you want to see on index.html by default, you should have something like in conf:
location /static {
alias /home/www/flask_project/static/;
try_files $uri $uri/index.html index.html;
}
Related
I have set up AWS Cloudfront Distribution for streaming objects from one of my S3 bucket. After generating urls, I am able to stream. Now since I have a server running in EC2 and my web app is backed by Nginx with already configured proxy_pass for the backend server. Now how do I use that generated cloudfront url for files to start playing them in my web app.
I am totally new to nginx following things I have tried
here is my nginx server config
server {
listen 8888;
server_name localhost;
}
location /app{
alias /opt/mw_web_app;
index index.html index.htm;
}
#Create proxy_pass for DataService.
location /service/{
proxy_pass http://server-ip:9003/;
proxy_set_header USER-IP $proxy_add_x_forwarded_for;
}
First fix your confguration and move the second curly brace to the end . then allow your server to be default server to assign all requests to this server
server {
listen 8888;
server_name localhost default_server;
location /app{
alias /opt/mw_web_app;
index index.html index.htm;
}
#Create proxy_pass for DataService.
location /service/{
proxy_pass http://server-ip:9003/;
proxy_set_header USER-IP $proxy_add_x_forwarded_for;
}
}
second, you sould use cloud front url direclty or assign CNAME using your own domain. if you use CF through your nginx CF will be useless with extra fees.
After a try and going to through Nginx Docs : Following worked for me and I a able to stream using cloudfront :
server {
listen 8888;
server_name localhost;
}
location /app{
alias /opt/mw_web_app;
index index.html index.htm;
}
#Create proxy_pass for DataService.
location /service/{
proxy_pass http://server-ip:9003/;
proxy_set_header USER-IP $proxy_add_x_forwarded_for;
}
#Create proxy_pass for DataService.
location /cloudfront/{
proxy_pass https://ddddddddd.cloudfront.net/;
}
}
PS: thanks #Ahmed Abdelazim for your time and yeah there was a syntax error also which u pointed out
I have what I believe to be a slightly convoluted Django/Gunicorn/NGINX stack that is giving me trouble as I try to migrate it from the django development server to a production setup with Gunicorn and NGINX. Specifically, I'm having trouble serving static files.
SYSTEM ARCHITECTURE: I have one physical server with a public IP address. This physical server hosts 3 VM's on a private virtual network (NAT). Each VM run's it's own django project on port 8001. I forward port 8001 on each VM to unique available ports on the physical machine. So, in summary, the architecture looks like the following:
PRIVATE VIRTUAL NETWORK VM's:
VM1 runs "site 1" on VM1 port 8001
VM2 runs "site 2" on VM2 port 8001
VM3 runs "site 3" on VM3 port 8001
HOST SERVER:
Publishes "site 1" on host port 8001 (VM port 8001 fwd.to Host port 8001)
Publishes "site 2" on host port 8002 (VM port 8001 fwd.to Host port 8002)
Publishes "site 3" on host port 8003 (VM port 8001 fwd.to Host port 8003)
This works really well for development with the django development server. I just need to include a port # in the URL. As in:
myserver.edu:8001 for site 1
myserver.edu:8002 for site 2
myserver.edu:8003 for site 3
For production I would like to setup NGINX to serve the sites as:
myserver.edu/site1 for site 1
myserver.edu/site2 for site 2
myserver.edu/site3 for site 3
I installed NGINX on the host machine and configured it to use TLS. The NGINX configuration on the host machine defines 3 locations below with following config. You can see that I use the proxy_pass to route traffic for each site to the Virtual Network on the host machine.
location /site1/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X_Forwarded-Proto $scheme;
proxy_pass http://192.168.122.243:8001/;
}
location /site2/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X_Forwarded-Proto $scheme;
proxy_pass http://192.168.122.244:8001/;
}
location /site3/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X_Forwarded-Proto $scheme;
proxy_pass http://192.168.122.245:8001/;
}
So any request for:
List item
myserver.edu/site1 goes to port 8001 on VM1
List item
myserver.edu/site2 goes to port 8001 on VM2
List item
myserver.edu/site3 goes to port 8001 on VM3
On VM1 I have a django site + gunicorn + NGINX with the following config (same setup on all VMs):
server {
listen 8001;
server_name 0.0.0.0;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/rcrv/bubbles/s2uds_user/gui;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/rcrv/bubbles/s2uds_user/bubs.sock;
}
}
My Site 1 root URL from urls.py is this: url(r'^$', gv.home),
BEHAVIOR UNDER THE ABOVE NGINX PRODUCTION CONFIG:
If I browse site 1 on VM1 from within the NAT with a URL such as:
192.168.122.243:8001/
This will work perfectly - Static and media file are served
If I browse from public IP space with a URL such as:
myerver.edu/site1/
This will render all dynamic content from django but will fail to serve static content (with a 404). My browser developer console shows that the browser is looking for the static content at https://myserver.com/static
Note that I expected it to look for static content at myserver/site1/static
If I modify that URL directly in the browser to be myserver.com/site1/static I can access the static content that was missing
ATTEMPTS TO MITIGATE/FIX INCLUDE:
I changed the location block on the NGINX config of the VM to be:
location = /site1/static/
No luck.
Debugging shows that the browser is still trying to find the static content at: myserver.edu/static
QUESTION:
How the heck do I modify or fix the configuration such that django includes that "/site1/" part in the static URL? I'm inclined to think that this problem is not an NGINX config issue but instead a django problem. Rather, I believe I need to tell django to prepend /site1/ to it's static URL.
Ideas? I've read numerous responses to similar django static file issues but yet on that fixes this.
Thank you.
UPDATE: I've started to figure this out. Here is what worked for me.
I created a /static/ directory at /var/www/static on each VM and set the STATIC_ROOT in the settings.py file to be this location, then ran collect static to copy all static content to this directory.
I then modified static file location block within the NGINX conf on the VM to be:
location /static/ {
root /var/www/;
}
Finally I modified the STATIC_URL in settings.py from: STATIC_URL = /static/ to STATIC_URL = /site1/static/
The result is the static content is now served in production under NGINX. The cause was my incomplete understanding of static content methods in general. Typing out the question here sort of clarified the problem and led me to the solution. Hopes this helps someone with a similar architecture. Now to fix the media files - likely the same approach.
I have a django app, with the following settings for static files:
STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = [STATIC_DIR,]
STATIC_ROOT = '/opt/static/'
I am running django using the follwoing gunicorn command:
gunicorn evee.wsgi -b 0.0.0.0:8000.
I have configured nginx to serve the static files and ssl using the following conf:
server {
keepalive_timeout 5;
listen 443 ssl;
server_name api.home.com;
client_max_body_size 4G;
error_page 500 502 503 504 /500.html;
# path for static files
root /opt;
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Ssl off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port 80;
proxy_set_header X-Forwarded-Proto $scheme;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://evee:8000;
}
}
Interesting part is that I am able to see the CSS in the client. For example, the request to https://secapi.ril.com/static/admin/css/base.css is successful and returns a 200 response. I can view all the static files at the URL mentioned, but django does not seem to use them. Have tried changing clients as well as private mode.
Am I doing something terribly wrong? This was working last time I checked.
Try adding static files path in your nginx config files as:
location /static/ {
alias /opt/static/;
}
Here mention complete path to your static folder. I guess in your case its /opt/static/
Here is how I solved this. Had to edit the nginx.conf file to configure an upstream instead of redirecting it to http directly and removed a few headers that were being set. No clue how different it is or why this works. The entire setup is running in Docker Swarm.
#### SECAPI #####
upstream app_server {
# for a TCP configuration
server evee:8000 fail_timeout=0;
}
server {
keepalive_timeout 5;
listen 443 ssl;
server_name api.home.com;
client_max_body_size 4G;
error_page 500 502 503 504 /500.html;
# path for static files
root /opt;
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://app_server;
}
}
I'm using nginx as reverse proxy with gunicorn for my Django app, and am new to webserver configuration. My app has a postgres backend, and the machine hosting it has Ubuntu 14.04 lts installed.
I have reason to suspect that my nginx configuration is not forwarding proxy set header to the Django app correctly. Is there a way I can see (e.g. print?) the host, http_user_agent, remote_addr etc. forwarded, on the linux command line to test my gut feel?
Secondly, how do I check whether my Django app received the correct forwarded IP? E.g. can I somehow print?
/etc/nginx/sites-available/myproject:
server {
listen 80;
server_name example.cloudapp.net;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/mhb11/folder/myproject;
}
location / {
proxy_set_header Host $host;
proxy_set_header User-Agent $http_user_agent;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://unix:/home/mhb11/folder/myproject/myproject.sock;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/mhb11/folder/myproject/templates/;
}
}
All you have to do is print out request.META at the Django project level to see what all of those values are being set to. This automatically happens for you if you get an error and debug is set to True (just scroll down, you'll see a big table with all request.META values populated therein).
Or you can print it yourself from your views.py, or if that doesn't work, then from any middleware you have. You can even write custom middleware for this. Let me know if you need further clarification on this, I can give you basic code snippets too.
This question was posted a long time ago but since I landed here when needed help, below are some code which I ended up using to attain the same goal for the help of other people.
def getClientIP(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[-1].strip()
else:
ip = request.META.get('REMOTE_ADDR')
return ip
I am facing the following probelm:
I have set up nginx to listen to two different upstream app servers running with uwsgi on different ports. The two applications use the same static files but depending on the nginx location the firstapplication or the secondapplication gets loaded:
server {
listen 80;
server_name localhost;
charset utf-8;
client_max_body_size 75M;
# Proxy connections to the application servers
# app_servers
location /firstapplication {
include /etc/nginx/mime.types;
proxy_pass http://app_servers_firstapplication/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
rewrite /?(?!/firstapplication)/(.+) /firstapplication/$1 last;
}
location /secondapplication {
include /etc/nginx/mime.types;
proxy_pass http://secondapplication/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
rewrite /?(?!/secondapplication)/(.+) /secondapplication/$1 last;
}
location ^~ /scripts/ {
alias /webapps/scripts/;
}
location ^~ /css/ {
alias /webapps/html/css/;
}
location ^~ /graphics/ {
alias /webapps/html/graphics/;
}
location ^~ /fonts/ {
alias /webapps/html/fonts/;
}
}
When I call mydomain/firstapplication or mydomain/secondapplication the initial page of the corresponding app gets loaded right.
But when the initial page of the app gets loaded and I click on a link in the app it is using the app's urls like /contact instead of /firstapplication/contact and therefore I geht a 404 error for every url I call in the application.
I wanted to solve this problem with location specific rewrites in nginx like this:
rewrite /?(?!/firstapplication)/(.+) /firstapplication/$1 last;
and
rewrite /?(?!/secondapplication)/(.+) /secondapplication/$1 last;
I used a negative lookbehind assertion to avoid a circular redirect when I load the page /fistapplication.
This rewrite regex should work I tested it in this online editor: http://regex101.com/r/yH7sP0/1
Unfortunately nginx does not redirect the application urls and they still lead to 404 errors.
Can I use nginx rewrite module to achieve my goal? Or what other approaches could I use to run two diffrent apps on the same nginx server?