django apps on nginx running separately from apache - django

I am installing production server for my django apps and I can not make it work. My configuration files can be found here.
Basically I have apache2 installed and running on port 80 for my php applications. I want to run my django apps on nginx with uwsgi, apart from apache2. So I am running nginx on port 8000.
When I open http://IP:8000/ I can see my site properly.
1. But how do I set it up with domain name?
I've set A tag in dns to IP. Now it hits apache2 "it works" page because it hits port 80 on default? So I need to proxy pass all requests to my domain.com? Something like this?
/etc/apache2/sites-enabled/domain.com:
<VirtualHost *:80>
ServerName domain.com
ProxyPreserveHost On
ProxyPass / http://IP:8000
</VirtualHost>
It does not work, so how do I pass all domain requests from apache to nginx?
2. How do I add another domain name? (new app)
Do I just create new socket file for new app, keep it on port 8000 and nginx will decide depending on domain name what conf file to use?
I have not found any similar tutorials, nginx usually handles static files and sends requests to apache2. However I want it other way.

Thanks for your answer. To make it work I had to set apache proxy like this:
<VirtualHost *:80>
ServerName www.domain.com
ProxyPreserveHost On
ProxyPass /static http://XX.XX.XX.XX:8000/static
ProxyPassReverse /static http://XX.XX.XX.XX:8000/static
ProxyPass / http://XX.XX.XX.XX:8000
ProxyPassReverse / http://XX.XX.XX.XX:8000
RewriteEngine On
RewriteCond %{REQUEST_URI} ^(.(?!\.css|js|gif|png|jpg|ico))*$
RewriteRule /(.*) http://XX.XX.XX.XX:8000/$1 [P,L]
</VirtualHost>
and enable proxy_http:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo service apache2 restart

1. How do you set it up with domain name?
In the server block of your nginx conf file set the server_name:
server {
listen 8000;
server_name www.my-django-domain-one.foobar;
#rest of your config regarding forwarding to django...
}
Your site will be available at http://www.my-django-domain-one.foobar:8000.
2. How do you add another domain name? (new app)
Nginx will not decide anything based on the conf filename. Create a new conf file or use the existing one (only matters in the sense of how you want to organize your configs)
server {
listen 8000;
server_name www.my-django-domain-two.foobar;
#rest of your config regarding forwarding to django...
}
However, I recommend an approach involving only one web server. Opinions on which to use vary of course but both of them can do what you want to achieve on their own. You add unnecessary complexity to your setup (e.g. two servers to keep patched) and -depending on your traffic- it may even have a significant impact on your performance.
Check out this tutorial to see how you could make your php apps work with nginx and php-fpm.

Related

How to deploy NuxtJs Application on Apache and access it with IP-URL instead of a domain?

Please note, this is my first nuxt-app trying to deploy on a staging server. We have a staging AWS server where many web applications are deployed as follows.
http://0.0.0.0/app1/public (Laravel)
http://0.0.0.0/app2 (static)
http://0.0.0.0/app3/public/api (Lumen)
http://0.0.0.0/app4/public (VueJs Static)
etc
http://0.0.0.0/app5 (Tried NuxtJs Universal SSR) failed
Note: SERVER: AWS instance has Ubuntu 18.04 with apache2
Now I want to deploy NuxtJs Universal Application (SSR), I have studied many articles, tried but failed.
What I have done so far:
Moved my all code to /var/www/html/app5
followed all the steps https://nuxtjs.org/docs/2.x/deployment/deployment-pm2
stuck, what to do next, and don't know how to access it in a browser with IP server.
pm2 list, command gives me the following result.
Progress Update:
I have finally found a new way to configure it on the main IP with virtual host configuration:
<VirtualHost *:80>
ServerName http://0.0.0.0
DocumentRoot /var/www/html/app5
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
My steps to configure NuxtJs app on IP-URL:
Created a new virtual host as above named nuxtjs.conf
a2dissite 000-default.conf, it was pointing to /var/www/html
a2ensite nuxtjs.conf
a2enmod proxy_http and a2enmod proxy
systemctl restart apache2
Yahoo! my main server IP-URL (http://0.0.0.0) was pointed to NuxtJs-application running perfectly :-)
But the problem was my all other websites stopped because they were running with 000-default.conf virtual host.
Please guide, what should be configuration, I don't want to close my all websites, they should be running as I mentioned at the start as http://0.0.0.0/name-of-web. How can I run the NuxtJs application as ip-url/app-name?
After a long time, my question was alone, so I decided to give it a partner with my answer, part a joke I have found the solution, and the following is my finding. Please update it if you have the more appropriate knowledge.
Enabled 81 port via AWS console.
Added following configuration in the nuxt.config.js to run the application on a specific port locally in the server.
server: {
port: 43411
}
Updated virtual host as follows.
NameVirtualHost *:81
<VirtualHost *:81>
ServerName http://0.0.0.0
DocumentRoot /var/www/html/app5
ProxyPass / http://localhost:43411/
ProxyPassReverse / http://localhost:43411/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Now I can access my nuxt-app on an IP URL as follows, along with all other deployed websites on this server.
http://0.0.0.0:81/

How to use Cloudflare's free SSL to force https on my Django application on Apache+mod_wsgi stack?

I wanted to use the free SSL (DNS) service provided by Cloudflare in my Django Application running on Apache + mod_wsgi stack. I can find setup examples for Nginx + uWSGI stack, but not for Apache + mod_wsgi stack so far. I was following this answer here https://stackoverflow.com/a/27650503/2051292 . But I couldn't convert the workaround from Nginx configuration to Apache/mod_wsgi. I'm facing few problems,
Even I use https to visit the web pages clicking on any of the internal links or submitting login/registration forms goes only to http pages.
(I actually want all the links to goto the https pages)
On the web page forms (login, registration) I'm getting CSRF Failed 403 Access Forbidden error. And I login at https page, but after verification the redirects to a http page with CSRF error.
Sometimes tweaking the configuration leads to redirect loop.
Would like to know the working configuration for using cloudflare free SSL with Apache + mod_wsgi stack and the Django settings also for the setup
EDIT: In case if you don't know, this is how Cloudflare's free SSL works.
I don't have an SSL certificate with me, I'm trying to use the free SSL by using the Flexible SSL. i.e. The connection from user to Cloudflare DNS will be https and the connection between Cloudflare and my server will be http.
Note: Currently I'm NOT using any middleware like django-sslify . But using it will help any other way. I'm okay with that also.
While I don't know the specifics of using Cloudflare, it should be the same Apache configuration once you have the appropriate certificates nave figured out the proxy settings mentioned in the other answer. Here's an example Apache configuration I have used for hosting Django with mod_wsgi and mod_ssl under CentOS. Under this configuration, we don't even listen to port 80. This assumes your web site is hosted at https://example.com/mysite, and that it is deployed to /var/www/html/mysite under the user mysiteuser with a virtualenv called mysitevenv:
LoadModule wsgi_module modules/mod_wsgi.so
LoadModule ssl_module modules/mod_ssl.so
WSGISocketPrefix /var/run/wsgi
NameVirtualHost *:443
Listen 443
<VirtualHost *:443>
ServerName example.com
ErrorLog /home/mysiteuser/apache_errors.log
WSGIDaemonProcess mysite-https python-home=/home/mysiteuser/.virtualenvs/mysitevenv
WSGIScriptAlias /mysite /var/www/html/mysite/mysite/wsgi.py process-group=mysite-https application-group=mysite-https
WSGIProcessGroup so-https
Alias /mysite/static/ /var/www/html/mysite/static/
SSLENGINE on
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLProtocol all -SSLv2
</VirtualHost>

Route a specific path to a specific EC2 instance using Route 53

I'm not sure if this is even possible, but if so I'm looking for the best way to do it.
Say I want to host my blog for example.com on it's own EC2 instance, and I want the path to my blog to be example.com/blog
Is it possible to route all requests to example.com/blog/* to one instance, and all other requests to that domain elsewhere?
My web server is Apache.
Thanks!
You can now do this with Application Load Balancer and path-based routing: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/tutorial-application-load-balancer-cli.html#path-based-routing-aws-cli
Certainly it's possible, but not with DNS nor with an ELB. The most common solution to this is to use a web server that issues a 301 or 302 redirect.
In your case, example.com would point to whatever the main site is. The web server (nginx or Apache httpd, perhaps) hosting example.com would have a redirect for example.com/blog/* that is found at another destination.
Here's an SO post on using Nginx for a redirect and for using Apache for a redirect.
Yes, but you would have to proxy your requests through an instance handling example.com. How you configure this depends on your web server.
Some examples on how to configure this:
nginx: http://wiki.nginx.org/HttpProxyModule
Apache: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
Since you are using Apache2 Server, so you can achieve this very easily by creating a Virtual Host.
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/vchost1.com.conf
Create Virtual Configuration using the above command, it copies the complete code of content from the default file provided by the apache2 Server.
sudo nano /etc/apache2/sites-available/vchost1.com.conf
start configuring host & domain according to your requirements
<VirtualHost *:80>
ServerAdmin admin#domain.com
ServerName domain.com
ServerAlias www.domain.com
DocumentRoot /var/www/domain.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
here also, you can multiple Virtual Host configurations in a single file, start configuring and enjoy hacking.
you can also multiple web applications in a single instance by using the same method and theis reference.
https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-virtual-hosts-on-ubuntu-18-04-quickstart

settings in apache for django app which need ssl for some pages

My django app (let me call it partlysecureapp)has an index page which is visible to all.All the other pages (reachable from links on index page) need the user to log in. I want to use the app with SSL in apache2.
I already have an app(say mysecureapp) deployed on apache with SSL, which has all pages needing login by the user. I have set the configurations for this as follows.
My apache2 is at /etc/apache2 which has the following directory structure.
/etc/apache2/
|--conf.d---*charset,security,localized-error-pages*
|---mods-available---...
|---mods-enabled---...
|---sites-available---default,default-ssl,ssl
|---sites-enabled---shortcut to ssl
|---apach2.conf
|---httpd.conf
|---ports.conf
|---magic
|---envvars
For the secureapp, I have set this in file sites-available/ssl
<VirtualHost *:443>
ServerAdmin webmaster#localhost
DocumentRoot /home/dev/python/django/mysecureapp
SSLEngine on
SSLOptions +StrictRequire
SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
...
WSGIScriptAlias /mysecureapp /home/dev/python/django/mysecureapp/mysecureapp.wsgi
Alias /site_media/ /home/dev/python/django/mysecureapp/media/
</VirtualHost>
This works perfectly..
To deploy my partlysecureapp,
http://127.0.0.1:8080/partlysecureapp/ need to show index page which is accessible to all.
but
../partlysecureapp/link1/
../partlysecureapp/link2/
../partlysecureapp/link3/
require login and should be served through ssl .
I think, I need to add another WSGIScriptAlias for my partlysecureapp. Do I need to add another DocumentRoot for the partlysecureapp? How to tell apache to serve the index page from port 8080 and others through ssl port?
As of now the /etc/apache2/httpd.conf is blank. Only the sites-available/ssl file has a VirtualHost element.
First of all, let's separate the concerns here: one thing is to require login, other is to require SSL. The former is specific to Django, and should be handled in your views; and for the latter, IMHO you should consider the possibiilty of serving everything through SSL, that would simplify your setup a lot. Sure, there's some overhead, and it's up to you to decide whether it matters or not for your particular case.
That said, for your proposed scenario:
To serve anything from plain HTTP, you need to listen to the port 80 (or, in your case, 8080). So you need a separate VirtualHost bound to that port, with a separate WSGI application for itself.
To allow a single path (your index file) from this virtual host, but require everything else to be served by the SSL protected one, you can use mod_rewrite:
RewriteEngine On
RewriteRule ^/partlysecureapp$ - [L,NC]
RewriteRule (.*) https://127.0.0.1/partlysecureapp%{REQUEST_URI} [L,R=301]
The first rule tells Apache not to perform any redirect if the path is exactly like your root path; the second redirects everything else to https (which will be handled by your *:443 virtual host).
(Note: you might want to serve /site_media without SSL as well)
Then you can simply add your WSGI alias; even if Django sends the user to a different page, Apache will ensure that page is served through SSL.
You final code would be something like:
<VirtualHost *:8080>
ServerAdmin webmaster#localhost
DocumentRoot /home/dev/python/django/partlysecureapp
RewriteEngine On
RewriteRule ^/partlysecureapp$ - [L,NC]
RewriteRule ^/site_media - [L,NC]
RewriteRule (.*) https://127.0.0.1/partlysecureapp%{REQUEST_URI} [L,R=301]
...
WSGIScriptAlias /partlysecureapp /home/dev/python/django/partlysecureapp/partlysecureapp.wsgi
Alias /site_media/ /home/dev/python/django/partlysecureapp/media/
</VirtualHost>
And your code for the SSL protected virtual host would be identical to the mysecureapp one (using partlysecureapp instead, of course; note also that you can have both apps running side-by-side, just pay attention to your MEDIA and STATIC paths).

multiple domains, multiple django projects, one server

Hi I'm new to apache and mod_wsgi and am trying to figure out how to configure both so that i can have www.example1.com use djangoproject1 and www.example2.com use djangoproject2.
I followed this tutorial to hook up example1.com to djangoproject1 and it works beautifully, but the tutorial doesn't exactly give the most detailed explanations for what is going on and why i need to do certain things.
what i have so far:
1) a dns zone for example2.com pointing to the server ip
2) installed python environment and django and started a new django project for djangoproject2 per the instuctions on the tutorial
I'm pretty sure i'm going to have to create a new wsgi config file and add a site configuration in /etc/apache2/sites-available/ called example2.com and then enable it, but i'm not sure about what else i'd need to do.
You can have 2 virtual hosts in your apache configuration.
The first virtual host on (default) - port 80
second one on port 81
In the virtual host, you can specify it this way:
NameVirtualHost *:80
<VirtualHost *.80>
DocumentRoot django_project_1_path
.... other config
WSGIScriptAlias / path_to_wsgi_config_1
</VirtualHost>
NameVirtualHost *:81
<VirtualHost *.81>
DocumentRoot django_project_2_path
.... other config
WSGIScriptAlias / path_to_wsgi_config_2
</VirtualHost>