I'm trying to get the following setup to work with gunicorn and nginx. Everything works until I add the second server config...
upstream app_server_djangoapp {
server localhost:8002 fail_timeout=0;
}
server {
listen 80;
server_name api.domain.tld;
access_log /var/log/nginx/guni-access.log;
error_log /var/log/nginx/guni-error.log info;
keepalive_timeout 5;
# Size in megabytes to allow for uploads.
client_max_body_size 20M;
# path for static files
root /home/username/webapps/guni/static;
location /docs/ {
autoindex on;
alias /srv/site/docs/buildHTML/html/;
}
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://app_server_djangoapp;
break;
}
}
}
server {
listen 80;
server_name flower.domain.tld;
location / {
proxy_pass http://localhost:5555;
}
What I'm I doing wrong? I need to have two subdomains one mapped to my django app and other mapped to my monitoring software on 5555 (flower)
log files states:
2014/11/21 12:03:27 [emerg] 962#0: unexpected end of file, expecting
"}" in /etc/nginx/sites-enabled/default:47
Your code is missing a closing "}" at the very end:
server {
listen 80;
server_name flower.domain.tld;
location / {
proxy_pass http://localhost:5555;
}
}
For future reference:
You can run nginx -t (with sudo if needed) to test the configuration before reloading nginx - this will give you a quite good description of any errors you might have in your configuration file(s).
Related
I have a Django project already using AWS SSL certificate from the Certificate Manager service. My application is accessible via HTTPS, however, it isn't redirecting automatically when accessing via HTTP.
My Nginx default.conf file before redirect (works like a charm!):
upstream django {
server my_app:8000;
}
server {
location / {
proxy_pass http://django;
}
}
After setting up the redirect:
upstream django {
server my_app:8000;
}
server {
listen 80;
if ($http_x_forwarded_proto = 'http'){
return 301 https://$host$request_uri;
}
location / {
proxy_pass http://django;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
And here is my Django settings.py for this:
.
.
.
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
CORS_ORIGIN_ALLOW_ALL = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 340505040
SECURE_SSL_REDIRECT = True
.
.
.
Then I'm getting http 400 (this is the Load Balancer Health Checker):
Edit 1
With this new setup, I'm getting http 301:
upstream django {
server my_app:8000;
}
server {
listen 80;
location / {
proxy_pass http://django/;
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
}
}
I've been looking around and didn't find any example that helps me. What can I try next?
On NGINX config put all the sites on SSL only
site on SSL
nginx/sites-available/sitex only listens to port 443
server {
# SSL configuration
#
listen 443 ssl ;
listen [::]:443 ssl ;
ssl_certificate /etc/letsencrypt/live/www.sitex.nl/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.sitex.cops.nl/privkey.pem; # managed by Certbot
server_name www.sitex.com; # managed by Certbot
access_log /var/log/nginx/sitex_access.log;
error_log /var/log/nginx/sitex_error.log;
location / {
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-Proto $scheme;
add_header Access-Control-Allow-Origin *;
proxy_pass http://127.0.0.1:8004;
}
}
All SSL/TLS requests to www.sitex.com are forwarded to localhost:8004.
And the SiteX Docker Image is picking up on that port.
nginx.conf
In the nginx.conf file the Virtual Hosts section is as follows
##
# Virtual Host Configs
##
include /etc/nginx/all_http_to_https.conf;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
all_http_to_https.conf
This file does the trick
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
I've deployed a Django application on DigitalOcean.
First off, when i try to secure this with https and ssl, I get this error.
when i run nginx -t :
nginx: [emerg] invalid parameter "server_name" in /etc/nginx/sites-enabled/django:12
nginx: configuration file /etc/nginx/nginx.conf test failed
upstream app_server {
server unix:/home/django/gunicorn.socket fail_timeout=0;
}
server {
#listen 80 default_server;
#listen [::]:80 default_server ipv6only=on;
listen 443 ssl
server_name domain.com
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
root /usr/share/nginx/html;
index index.html index.htm;
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
# Your Django project's media files - amend as required
location /media {
alias path/to/media;
}
# your Django project's static files - amend as required
location /static {
alias path/to/static;
}
# Proxy the static assests for the Django Admin panel
location /static/admin {
alias path/to/staticadmin;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://app_server;
}
}
server {
listen 80;
server_name domain.com;
return 301 https://$host$request_uri;
}
Furthermore, I can access the website using the ip address but not the domain name registered.It results in a 400 bad request page.
Could this be an issue with the settings.py ?
for reference in settings.pyALLOWED_HOSTS=['*']. What list do I provide in the ip_addresses() function?
Are these two problems related?
using Django v1.10.5
You're missing semicolons on a bunch of lines, that's why nginx -t is failing.
Trying to setup Nginx handling 2 domains I stucked with some problems. While my setup with two domains works correctly with static html handling, tried to push forward and start two python apps behind Nginx. I tried with some differents wsgi containers, and different micro frameworks, but the problem is that Nginx can't handle virtual hosts, rather it serves only one app at both domain adresses.
Here is Nginx conf:
user www-data;
worker_processes 8;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_names_hash_bucket_size 64;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
server {
listen 80;
server_name www.domainA.com;
root /var/www/domainA.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Originating-IP $remote_addr;
proxy_set_header HTTP_REMOTE_ADDR $remote_addr;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header CLIENT_IP $remote_addr;
proxy_pass http://127.0.0.2:7000;
}
}
server {
listen 80;
server_name www.domainB.com;
root /var/www/domainB.com;
location / {
... ... blah blah...same story...except this proxy pass.....
proxy_pass http://127.0.0.1:5000;
}
}
}
Any help ?
EDIT:
Just tried to add empty server block as 1st block and it return 404.
Are these outward facing websites?
If you put the full ip in your listen clause you should start working correctly.
listen 512.548.595.485:80;
Right now you have the server ip for both sites which is causing a conflict.
Hope this helps.
In the senario where virtual hosts share an ip and port, nginx selects the right virtual host by comparing the Host header sent by the client to each servers' server_name entry. If you have curl use the following to see exactly what you're sending for the Host header:
curl -s --trace-ascii - http://www.domainA.com | grep 'Host:'
To make your server_name more flexible use the .example.com notation. This is shorthand for example.com and *.example.com. Or just add as many server_name entries as you need.
Next confirm your apps are listening on the right ips and ports. Shell into your server and try:
curl -I 'http://127.0.0.1:5000'
curl -I 'http://127.0.0.2:7000'
Finally I ended with such problem. In testing conditions I didn't add all flavours which would make Nginx satisfied. Then I found THIS LINK :
If the “Host” header field does not match a server name, NGINX will route the request to the default server for this port. The default server is the first one listed in the nginx.conf file. This will be overridden if the default_server parameter is set in the listen directive within a server context. An example is given below.
Nginx docs and tutorials are dispersed on few web locations so finding few doesn't mean that you got all answers you need.
I think, this is your solution. Create a BASH file whose name should be virtualhost.sh. Copy and paste the following code:
#!/bin/bash
domain=$1
root="/data/$domain"
block="/etc/nginx/sites-available/$domain"
# Create the Document Root directory
mkdir -p $root
# Assign ownership to your regular user account
chown -R $USER:$USER $root
# Create the Nginx server block file:
tee $block > /dev/null <<EOF
server {
listen 80;
listen [::]:80;
root /data/$domain;
index index.php index.html index.htm;
server_name $domain www.$domain;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
include fastcgi_params;
}
location ~ /\.ht {
access_log off;
log_not_found off;
deny all;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
access_log off;
log_not_found off;
expires 30d;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
}
EOF
# Link to make it available
ln -s $block /etc/nginx/sites-enabled/
# Test configuration and reload if successful
nginx -t && service nginx reload
You need call this BASH file:
virtualhost.sh www.yourdomain.com
I have set up uwsgi and nginx to serve a flask website that I'm working on but it refuses to display the css file even though it appears in the body of the page correctly and I can view it. It does not change the styling of the page.
I use the following nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
gzip on;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 500;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/xml text/css
text/comma-separated-values
text/javascript
application/x-javascript
application/atom+xml;
# Configuration containing list of application servers
upstream uwsgicluster {
server 127.0.0.1:8080;
# server 127.0.0.1:8081;
# ..
# .
}
# Configuration for Nginx
server {
# Running port
listen 80;
# Settings to by-pass for static files
location ^~ /static/ {
# Example:
# root /full/path/to/application/static/file/dir;
root /app/static/;
}
# Serve a static file (ex. favico) outside static dir.
location = /favico.ico {
root /app/favico.ico;
}
# Proxying connections to application servers
location / {
include uwsgi_params;
uwsgi_pass uwsgicluster;
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;
}
}
}
I'm using Nginx as webserver, with a reverse proxy to a gunicorn django server.
I tried using the SSLRedirect snippet from here:
http://djangosnippets.org/snippets/85/
Because this snippet would always return false from is_secure() with my setup, resulting in a redirect loop, I had to make some changes.
SSL works, but when I access http://domain.net/main it doesn't redirect to https://domain.net/main. Isn't it supposed to do that?
Below outlines the modification I made:
if 'HTTP_X_FORWARDED_PROTOCOL' in request.META:
return True
And in my nginx conf (I only need SSL, http not required):
server {
listen 8888;
server_name domain.net;
ssl on;
ssl_certificate /path/to/domain.pem;
ssl_certificate_key /path/to/domain.key;
# serve directly - analogous for static/staticfiles
location /media/ {
root /path/to/root;
}
location /static/ {
root /path/to/root;
}
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://127.0.0.1:8881/;
# note this line
proxy_set_header X-Forwarded-Protocol https;
}
}
Just do it entirely with nginx. No need to involve Django at all:
server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
server {
listen 443;
# The rest of your original server config here
}