nginx unknown directive "upstream" - django

I'm using nginx as a proxy server to forward requests onto my gunicorn server. When I run sudo nginx -t -c /etc/nginx/sites-enabled/mysite I get the following error.
[emerg]: unknown directive "upstream" in /etc/nginx/sites-enabled/mysite:1
configuration file /etc/nginx/sites-enabled/mysite test failed
Any idea how to fix it? This is my nginx config:
upstream gunicorn_mysite {
server 127.0.0.1:8000 fail_timeout=0;
}
server {
listen 80;
server_name example.com;
access_log /usr/local/django/logs/nginx/mysite_access.log;
error_log /usr/local/django/logs/nginx/mysite_error.log;
location / {
proxy_pass http://gunicorn_mysite;
}
}
I'm running Ubuntu 10.04 and my nginx version is 0.7.65 which I installed from apt.
This is the output when I run nginx -V
nginx version: nginx/0.7.65
TLS SNI support enabled
configure arguments: --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx.lock --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --with-debug --with-http_stub_status_module --with-http_flv_module --with-http_ssl_module --with-http_dav_module --with-http_gzip_static_module --with-http_realip_module --with-mail --with-mail_ssl_module --with-ipv6 --add-module=/build/buildd/nginx-0.7.65/modules/nginx-upstream-fair

When you tell nginx to load that file directly, it starts at the global context. The upstream directive is only valid in the http context. When that file is included normally by nginx.conf, it is included already inside the http context:
events { }
http {
include /etc/nginx/sites-enabled/*;
}
You either need to use -c /etc/nginx/nginx.conf or make a small wrapper like the above block and nginx -c it.

I am using nginx version: nginx/1.4.1 on EC2 Ubuntu. I was getting this error:
nginx: [emerg] "upstream" directive is not allowed here in /etc/nginx/nginx.conf
To get my instance running I had to wrap the upstream and server sections in an http { } section. It then complained about missing event section. So I added that as follows:
events {
worker_connections 1024;
}
It worked fine after those fixes, this is my first effort so I was guessing my way through.

Turns my nginx config was ok. The problem was with my gunicorn server was not running properly.

Related

Nginx server not using project config

I am trying to create a configuration for the Nginx web server for my Django project. I would like to store the configuration of the web server in my project files.
As I am using MacOS, the /sites-enabled directory was not present in the /usr/local/etc/nginx directory, so I've created it. In the /usr/local/etc/nginx/sites-enabled directory I have made a symbolic link to the project which seems to work.
In the nginx.config file in the /usr/local/etc/nginx directory I have updated the file to make it see the sites-enabled directory:
http {
include /usr/local/etc/nginx/sites-enabled/*;
The nginx -t command lists the following if I input incorrect data in my project nginx.conf file:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
and correctly recognizes changes to it if I make some intentional errors:
nginx: [emerg] invalid parameter "server_name" in /usr/local/etc/nginx/sites-enabled/linkem-all:6
nginx: configuration file /usr/local/etc/nginx/nginx.conf test failed
The problem is that despite my changing the port to listen to in the nginx.conf file located in my project:
server {
# port nginx will be listening to
listen 8000;
# server ip address
server_name 127.0.0.1.;
# logs stored within the project
access_log path/to/nginx-acces.log;
error_log /path/to/nginx-error.log;
# pass traffic from nginx to the gunicorn server
location / {
proxy_pass http://127.0.0.1:5432;
}
# static files location served with alias for explicit path
location /static {
alias ./static;
}
}
after running the nginx server I get the error caused by nginx trying to bind to port 8080, its default setting.

Nginx unable to proxy django application through gunicorn

I'm trying to deploy a Django app in a Ubuntu Server 18.04 using Nginx and Gunicorn. Every tool seems to work properly, at least, from logs and status points of view.
The point is that if I log into my server using SSH and try to use curl, gunicorn is able to see the request and handle it. However, if I write directly my IP, I get simply the typical Welcome to nginx home page and the request is completely invisible to gunicorn, so it seems nginx is unable to locate and pass the request to the gunicorn socket.
I'm using nginx 1.14.0, Django 2.2.1, Python 3.6.7, gunicorn 19.9.0 and PostgreSQL 10.8.
This is my nginx config
server {
listen 80;
server_name localhost;
location /favicon.ico { access_log off; log_not_found off; }
location /static/ {
alias /home/django/myproject/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
And these are my gunicorn.sock
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
and gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=django
Group=www-data
WorkingDirectory=/home/django/myproject/myproject
ExecStart=/home/django/myproject/myproject/myproject/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
MyProject.wsgi:application
[Install]
WantedBy=multi-user.target
I've been following this guide (https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04), where most of all has worked as expected, but with the difference that my project is not a completely new one as in the tutorial, but cloned from my git repo (however, it's tested and the code works properly)
I was expecting the Django admin to be accessible from my browser already with this config, but it's not. I try to access my IP from my browser and I get Welcome to nginx but also 404 if I visit /admin. In addition, the gunicorn logs shows no requests.
In the other hand, if I log through SSH into my server and I execute curl --unix-socket /run/gunicorn.sock localhost, I can see in the gunicorn logs the request done by curl.
Any help is welcome.. I've been here for hours and I'm not able to get even 1 request from outside the server.
PD: it's also not something related to the ports in the server, since when I access the root of my IP, I receive the nginx answer. It just seems like Nginx has no config at all.
in your nginx config, you should use your proper server_name instead of localhost
server_name mydomain.com;
If not, you will fall back to the default nginx server, which returns the "welcome to nginx" message. You can change which virtual server is default by changing the order of servers, removing the nginx default, or using the default_server parameter. You can also listen to multiple server names.
listen 80 default_server;
server_name mydomain.com localhost;
If the Host header field does not match a server name, NGINX Plus routes the request to the default server for the port on which the request arrived. The default server is the first one listed in the nginx.conf file, unless you include the default_server parameter to the listen directive to explicitly designate a server as the default.
https://docs.nginx.com/nginx/admin-guide/web-server/web-server/#setting-up-virtual-servers
Remember that you have to reload the nginx config after making changes. sudo nginx -s reload for example.
Finally, I've got it working properly. You were right about the config of nginx, although my real problem was not to delete/modify default config file for nginx in sites_enabled folder. Thus, when I was setting listen 80 default_server I got the following error
[emerg] 10619#0: a duplicate default server for 0.0.0.0:80 in
/etc/nginx/sites-enabled/mysite.com:4
Anyway, I had a problem with the static files which I still not knowing why it works like that. I needed to set DEBUG = True to be able to see static files of the admin module.
I'll keep on investigating the proper way of serving static files in production for the admin panel.
Thank you so much for the help!

Nginx in Docker container gets `connection reset` error, but works fine without a container

I've a simple setup of 3 components that I've wrapped into docker containers:
PostgreSQL database, container named workflows-db
Django + uWSGI web server on port 8000, container named workflows-django
Nginx reverse proxy, container named workflows-nginx
I'm running Postgres and Django as containers and they work fine. Now, I want to add Nginx. If I simply install Nginx locally on the host machine (without Docker) and run it, my setup works fine.
But if I put exactly the same configuration of Nginx into a separate docker container, it fails to respond to https:// requests 100% of times:
This site can’t be reached
The connection was reset.
ERR_CONNECTION_RESET
Here's my configuration mysite.conf, put in /etc/nginx/sites-available/mysite.conf and /etc/nginx/sites-enabled/mysite.conf:
upstream django {
server workflows-django:8000;
}
server {
listen 80;
server_name workflows.devbg.us;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name workflows.devbg.us;
ssl_certificate /etc/ssl/private/bostongene.crt;
ssl_certificate_key /etc/ssl/private/bostongene.key;
charset utf-8;
client_max_body_size 75M;
location /media {
alias /srv/workflows/media;
}
location /static {
alias /srv/workflows/static;
}
location / {
# We can talk to upstream django either via uwsgi or just http proxy
# uwsgi:
uwsgi_pass django;
include /etc/nginx/uwsgi_params;
# http proxy:
#proxy_set_header Host $host;
#proxy_pass http://django
}
}
I run nginx container after django and postgres containers with the following parameters:
docker run --name workflows-nginx --volumes-from workflows-db --volumes-from workflows-django --link workflows-django:workflows-django -p 80:80 -p 443:443 -d workflows-nginx
The file /etc/hosts on my host machine looks as follows:
127.0.0.1 localhost
127.0.0.1 workflows-db
127.0.0.1 workflows-django
127.0.0.1 workflows-nginx
127.0.0.1 workflows.devbg.us
Do you have any ideas about how to troubleshoot this? Nginx error.log doesn't contain these errors.
The official docker image at docker hub seems to be stripped of nginx uwsgi adapter.
So, I just manually created my own Nginx Dockerfile from debian:jessie and voila. Seems that uwsgi adapter is available somewhere in nginx-common or nginx-full Debian packages.
My Dockerfile:
FROM debian:jessie
RUN apt-get update && apt-get install -y nginx \
ca-certificates \
gettext-base
COPY yoursite.conf /etc/nginx/sites-available/yoursite.conf
COPY yoursite.conf /etc/nginx/sites-enabled/yoursite.conf
COPY yoursite.crt /etc/ssl/private/
COPY yoursite.key /etc/ssl/private/
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
EXPOSE 80 443
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]

Amazon EC2 Deployment Not Working When IP Address Typed Into Browser Suspect Ngnix Problems

I am nearing the last step of deploying my Django app and I think I am having a Nginx problem. This is my first time deploying, so give me a break.
Basically, the problem is that when I navigate to my public IP on my browser I am getting a webpage is not available error.
I am thinking it is an issue with how I am writing out my directory structure in my Nginx configuration script, but am unsure. I am following a tutorial and don't really understand the script they are asking me to run.
Here is my app's directory structure within my server...
/home/ubuntu/flower_shop/flowershop
Here is my Nginx's file that configures Nginx
server {
listen 80;
server_name 54.213.141.60;
location = /favicon.ico { access_log off; log_not_found off;}
location /static/ {
root /home/ubuntu/flower_shop/flowershop;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/flower_shop/flowershop/flowershop.sock;
}
I am creating the above file by typing the following into my command line...
sudo vim /etc/nginx/sites-available/flower_shop
Can you see anything obvious that I am doing wrong? Gunicorn is set up fine and my app works on my local host. I have tried restarting Nginx, but I get the same results.
Hope you have done the following step:
sudo ln -s /etc/nginx/sites-available/flower_shop /etc/nginx/sites-enabled/flower_shop
Some other diagnostic commands which will help pin down the problem:
Supply nginx error and access logs
output of netstat -tulpn | grep nginx
In ssh session do curl -D - http://localhost:80
Try replacing the above snippet with the following extremely simple server config. Notice the only filtering it has for now is for port 80. It assumes your gunicorn is serving at 8080. Change port appropriately, if required.
```
server{
listen 80;
location / {
proxy_pass http://localhost:8080;
}
}
```

Nginx: listen to 8080 for proxy_pass, but not 80

I can't seem to make this nginx config work on port 80. I tried to deploy a django application using nginx and gunicorn. I used the following command to run gunicorn:
gunicorn myproj.wsgi:application --bind=127.0.0.1:8001 --workers=9
The following is the nginx config file /etc/nginx/sites-enabled/myproj:
server {
listen 8080;
location / {
proxy_pass http://127.0.0.1:8001;
}
location /static/ {
root /webapps/myproj/;
}
}
Everything works fine except that I have to enter http://localhost:8080/ locally or http://xxx.xxx.xxx:8080/ for the application to run correctly. Without the port number 8080, the page would not be found.
However, if I change the listen 8080; into listen 80; in the config file (myproj) and enter http://localhost/ locally or http://xxx.xxx.xxx/ remotely, the page only shows the welcome message from nginx. Nginx seems not forwarding the request to my application. What was the problem?
You need to specify domain or IP to bind to.
listen XXX.XXX.XXX:80;
Probably because other server with listen 80; exists.
You can remove other server defenition. Or change listen 80; to listen 80 default_server;. Or use server_name directive for name-based process.
Read this about how nginx decides which server should process the request: http://nginx.org/en/docs/http/request_processing.html