Nginx + Django + Phpmyadmin Configuration - django

I've migrated my server to amazon ec2, and trying to set up the following environment there:
Nginx in the front serving static content, passing to django for dynamic content. I also would like to use phpmyadmin in this setting.
I am not a server admin, so I simply followed a few tutorials to make nginx and django up and running. But I've been working for two days now trying to hook phpmyadmin to this setup, with no avail. I am sending my current server configuration now, how can I serve phpmyadmin here?
server {
listen 80;
server_name localhost;
access_log /opt/django/logs/nginx/vc_access.log;
error_log /opt/django/logs/nginx/vc_error.log;
# no security problem here, since / is always passed to upstream
root /opt/django/;
# serve directly - analogous for static/staticfiles
location /media/ {
# if asset versioning is used
if ($query_string) {
expires max;
}
}
location /admin/media/ {
# this changes depending on your python version
root /path/to/test/lib/python2.7/site-packages/django/contrib;
}
location /static/ {
# if asset versioning is used
if ($query_string) {
expires max;
}
}
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://localhost:8000/;
}
# what to serve if upstream is not available or crashes
error_page 500 502 503 504 /media/50x.html;
}

This question should rightly belong to http://serverfault.com
Nevertheless, the first thing you ought to do is to configure a separate subdomain for your phpmyadmin for ease of administration.
So there will be two apps running with nginx as reverse proxy, one nginx server for your above django app and another server (also known as virtualhost) for your phpmyadmin with a configuration similar to this:-
server {
server_name phpmyadmin.<domain.tld>;
access_log /srv/http/<domain>/logs/phpmyadmin.access.log;
error_log /srv/http/<domain.tld>/logs/phpmyadmin.error.log;
location / {
root /srv/http/<domain.tld>/public_html/phpmyadmin;
index index.html index.htm index.php;
}
location ~ \.php$ {
root /srv/http/<domain.tld>/public_html/phpmyadmin;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /srv/http/<domain.tld>/public_html/phpmyadmin/$fastcgi_script_name;
include fastcgi_params;
}
}
Each of your server configuration can point at different domain names via the server_name configuration. In this example, server_name phpmyadmin.<domain.tld>;
Here's an example taken from http://wiki.nginx.org/ServerBlockExample
http {
index index.html;
server {
server_name www.domain1.com;
access_log logs/domain1.access.log main;
root /var/www/domain1.com/htdocs;
}
server {
server_name www.domain2.com;
access_log logs/domain2.access.log main;
root /var/www/domain2.com/htdocs;
}
}
As you can see, there are two declarations of server inside the large http brackets. Each declaration of the server should contain the configuration you have for django and another for the configuration of phpmyadmin.
2 "virtual hosts" ("server" instances) taken care by nginx.

Related

Adding SSL to the Django app, Ubuntu 16+, DigitalOcean

I am trying to add my SSL certificate to my django application according to this tutorial. I can turn on my website using 'https://ebluedesign.online'. But web browsers return something in style 'The certificate can not be verified due to a trusted certificate authority.' After accepting the messages, my page is displayed correctly.
My nginx file looks like this:
upstream app_server {
server unix:/home/app/run/gunicorn.sock fail_timeout=0;
}
server {
#listen 80;
# add here the ip address of your server
# or a domain pointing to that ip (like example.com or www.example.com)
server_name ebluedesign.online;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/ebluedesign.online/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/ebluedesign.online/privkey.pem;
keepalive_timeout 5;
client_max_body_size 4G;
access_log /home/app/logs/nginx-access.log;
error_log /home/app/logs/nginx-error.log;
location /static/ {
alias /home/app/static/;
}
# checks for static file, if not found proxy to app
location / {
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
server {
listen 80;
listen [::]:80;
server_name ebluedesign.online;
return 301 https://$host$request_uri;
}
My certificates are also visible here:
/etc/letsencrypt/live/ebluedesign.online/...
How can I solve this problem with SSL certificate. I use free SSL by https://letsencrypt.org/.
EDIT:
What is odd is if you go to http://bluedesign.online/ it works fine even though your file makes it seem as if port 80 isn’t listened too at all. Do you happen to have two setup files in nginx? It is possible that the one you posted is not being used.
I’ve followed this tutorial many times with success. You could try using it from scratch if you have the opportunity: https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04

How to configure nginx for websocket. I have django for REST in backend. The standard configurations i found over net wont work for nginx websocket

I have nginx to server to browser. I want nginx to serve for websocket requests from browser. Nginx has internally proxy to django (gunicorn uwsgi) using proxy configs. I am not able to set up the config in nginx for websocket. Tried different configs from internet but no success. My default file in nginx config file :
server {
listen 80 default_server;
listen [::]:80 default_server;
root /usr/share/gmc/dist;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404 /index.html index.js;
}
location ~ /redfish.* {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8000;
}
}
These are the basic settings you need to apply for your django-project:
server {
listen 80;
server_name **Server Name or IP**;
#Website LOGO:
location = /favicon.ico { access_log off; log_not_found off;}
#Static Files like CSS, JS
location = /static/ {
root /home/hitshell/website/project/
}
#Media Files like Images, Videos etc.
location = /media/ {
root /home/hitshell/website/project/
}
#proxy
location = / {
include proxy_params;
proxy_pass http://unix:/home/hitshell/website/project/project.sock;
}
}
REFERENCE:
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-django-with-postgres-nginx-and-gunicorn
https://www.shellvoide.com/hacks/installing-django-application-with-nginx-mysql-and-gunicorn-on-ubuntu-vps/
The First one has some missing configurations in the middle of the tutorial.

Configure Django App as nginx location

I am trying to deploy a Django app along a static html website. The general www.example.com will provide the basic website. The URI /app should then proxy to a Gunicorn WSGI server. The nginx configuration in sites-enabled looks as follows:
upstream gunicorn {
server 127.0.0.1:8000;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/website;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://gunicorn;
}
}
I am getting a 404 error when trying www.example.com/app. It seems the URI gets messed up somehow. The complete URL that is created is http://www.example.com/accounts/login/?next=/app/
Setting up the App alone exactly following this tutorial http://hackedexistence.com/project/raspi/django-on-raspberry-pi.html does work.
Is the setup I am aiming at even possible? And if yes, where is my misunderstanding of the location concept?
You need to set the SCRIPT_NAME header in your location directive.
proxy_set_header SCRIPT_NAME /app;
See this blog post for an example.

taking a django site down for maintenance?

I am running django with nginx/gunicorn. I am not deeply familiar with how nginx and gunicorn work, but suppose that I want to take my django site down for maintenance.
I assume I would be wanting to redirect to some simple maintenance page by going into the nginx/gunicorn settings and redirecting something but I could be wrong.
What is the correct (easiest) way to do this?
EDIT adding nginx config proxy statements:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
EDIT 2: adding nginx sites-enabled file
upstream app_server {
server 127.0.0.1:9000 fail_timeout=0;
}
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
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 /home/django/mysite/media;
}
# your Django project's static files - amend as required
location /static {
alias /home/django/mysite/static_dump;
}
location / {
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header Host $http_host;
#proxy_redirect off;
#proxy_pass http://app_server;
if (-f /usr/share/nginx/html/index.html) {
return 503;
}
}
error_page 503 #maintenance;
location #maintenance {
rewrite ^(.*)$ /503.html break;
}
}
One of the ways to do is to add the maintenance page somewhere in the server, and then in your nginx file ( In the sites-enabled folder) redirect requests to the site to that maintenance page.
Your nginx page should contain:
server_name myhost.example.com;
root /path/to/html/file/directory;
index index.html;
Only the above 3 lines are enough

Nginx cannot serve backend's static files

Nginx is set up with both frontend and backend services in Docker - both are working without any issues apart from backend static files which are not being served by nginx (http://api.example.com/static/...). Since frontend is SPA and consists of static files already - they have no issues being served from within nginx container. However, nginx is not serving backend static files. The static files are definitely in the nginx container (/home/app/web/static/) - however nginx is giving the following error when checked in the console - this is probably because the CSS file below would return 404 (which is html page) - hence it cannot apply html to CSS . Nginx log files are clear.
Refused to apply style from
http://api.example.com/static/admin/css/responsive.css because its
MIME type ('text/html') is not a supported stylesheet MIME type, and
strict MIME checking is enabled.
P.S. Backend framework is Django whereas Frontend is Vue.
nginx.conf file
upstream api {
server backend:8000;
}
server {
listen 80;
server_name example.com;
root /usr/share/nginx/html;
index index.html index.htm;
# frontend
location / {
try_files $uri $uri/ /index.html;
}
location #rewrites {
rewrite ^(.+)$ /index.html last;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
server {
listen 80;
server_name api.example.com;
# backend
location ~ ^/(admin|api) {
proxy_pass http://api;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
# backend static files (django)
location /static/ {
autoindex on;
alias /home/app/web/static/;
}
}