nginx serving passenger on subdirectory - ruby-on-rails-4

I got some rails 4 apps and I need them to be in /subdirectory of my domain, I am doing this with location directive, the problem is that they don't know that they are in that specific directory and all /link are going to mydomain/link instead of mydomain/app-a/link
this is the configuration that I use for one of the apps, I got it from official passenger docs
location ~ ^/events(/.*|$) {
alias /home/acm/acm-events/public$1;
passenger_base_uri /events;
passenger_app_root /home/acm/acm-events;
passenger_document_root /home/acm/acm-events/public;
passenger_enabled on;
}

Related

How to associate only a subdomain to my Django App on Digital Ocean?

We already have a website called X.com. Now I am building a Django App on a Digital ocean Droplet. I am able to access it using the IP-address.
But we want to have it called reporting.X.com for sharing it with our users.
On my domain providers, I already added an A record like the below
Host- reporting
Type - A
Content - <ip-address> of digital ocean droplet
However I keep getting the following message when I try to access reporting.X.com.
What should I do?
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.
Thank you for using nginx.
Okay I have resolved the issue. So I will answer this for future reference of other people.
You need to check 2 important places.
/etc/nginx/sites-enabled/<your_project>
If you want your django app with just the subdomain, your project file in sites-enabled should look like below.
server {
listen 80;
server_name <ip-address> .X.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/<user>/<project>;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/<user>/<project>.sock;
}
The dot in front of X.com is not a typo. This basically says any sub domain for X.com.
settings.py file in Django App
You have to set ALLOWED_HOSTS this way.
ALLOWED_HOSTS = ['ip-address', '.X.com']
Again X.com is preceded with a dot.
In the question, I already mentioned that I created an A record with following details.
Host- reporting
Type - A
Content - <ip-address> of digital ocean droplet
After this, restart your nginx server.
sudo systemctl restart nginx
Now, theoretically it should work. But if it doesn't (as it didn't for me), you have to shutdown and restart your droplet.
sudo shutdown -r now
My Django app started to work after this activity.
Hope it helps.

Is it necessary to include sites-enabled directory within nginx.conf?

I am following Setting up Django and your web server with uWSGI and nginx tutorial. I was stuck on part Configure nginx for your site. I tried everything that I have found searching the internet, mainly I was trying to fix my config mysite_nginx.conf file, but it seems now that it was correct all the time.
This is my config file mysite_nginx.conf which of course is symlinked from /usr/local/etc/nginx/sites-enabled/.
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
server 127.0.0.1:8001;
}
# configuration of the server
server {
listen 8000;
server_name localhost;
charset utf-8;
client_max_body_size 75M;
location /media {
alias /Users/username/dev/my_site/mysite/media;
}
location /static {
alias /Users/username/dev/my_site/mysite/static;
}
location / {
uwsgi_pass django;
include /Users/username/dev/my_site/mysite/uwsgi_params;
}
}
The problem I faced
Visiting localhost:8000/media/img.jpg or localhost:8000/static/img.jpg always was returning 404 Not Found. In nginx logs all of the requests were mapped to /usr/local/Cellar/nginx/version/html/ which is a symlink to the /usr/local/var/www/ where index.html and 5xx.html files are present.
My static/ and media/ were added to the /usr/local/Cellar/nginx/version/html/ so in nginx error logs I saw requests to /usr/local/Cellar/nginx/version/html/static/img.jpg.
The solution that worked for me
In nginx.conf file I have included path to the sites-enabled. After this all of my requests where mapped to the absolute paths that I have added as an alias of the location and everything worked as expected.
...
http {
include mime.types;
include /usr/local/etc/nginx/sites-enabled/*.conf;
default_type application/octet-stream;
...
The Question
In the tutorial that I mentioned there was no mention about this, so I suppose it should work without editing nginx.conf file? But it didn't worked for me, am I missing something?
First of all there is no restriction or necessity to follow one approach. You can have all your config in a single nginx.conf or you can split it into multiple files and include them, or you can include specific patterns from a directory.
Different OS distribution may use different config type of default config setup. The common one being usage of a nginx.conf using include site-enabled/*.conf; and include conf-enabled/*.conf;
The logic is that your create your actual config in sites-available and conf-available directory and you just symlink them in the sites-enabled and conf-enabled directory respectively. So tomorrow if you want to disable a config then instead of renaming or deleting it you just delete the symlink from xxxx-enabled directory. This is just a convention so it easier for you to manage virtual hosts related to different sites in their own files.
By default these have some default configs which are for the demo nginx page. Before setting up your config you should disable this, so that it doesn't mess up with your config.
Now sometimes the include may not be part of the default nginx.conf. Because you installed nginx using brew the config used in that installation is different. If you check the file it has below include
include servers/*;
So the expectation is to put it at different place. So you have to be aware that the base config is nginx.conf (that also can be changed by compiling nginx from source). It can then include other configs or choose not to and just have a default server in nginx.conf itself. Before following any tutorial do read your nginx.conf file first.

Django project deployment: cannot load static files

I'm deploying a Django project using:
virtualenv
nginx
gunicorn
following this tutorial: https://www.digitalocean.com/community/tutorials/how-to-deploy-a-local-django-app-to-a-vps
My configuration
django settings
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
STATIC_URL = '/static/'
/etc/nginx/sites-available/esmart2
GNU nano 2.0.9 File: /etc/nginx/sites-available/esmart2
server {
server_name 192.168.30.17;
access_log off;
location /static/ {
alias /new_esmart/esmart2/static/;
}
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
}
}
Running
(esmart_env) [root#eprssrv09 esmart2]# /new_esmart/esmart_env/bin/gunicorn --bind 192.168.30.17:8001 esmart2.wsgi:application
My Django project is running but:
Not Found: /static/admin/css/login.css
Any advice?
UPDATE 1
I think that nginx settings are been avoided:
deleting any reference in 'sites-enabled' folder, django project runs and the problem concerning static files remain.
UPDATE 2
if in Django settings debug=True I get
Not Found: /static/admin/css/base.css
Not Found: /static/admin/css/login.css
Not Found: /static/admin/css/base.css
It seems I solved BUT I don't think is the better solution. I mean, it's a good solution depending on the project requirements: mine allows using this solution.
install package
pip install whitenoise
on wsgi.py I added:
from whitenoise.django import DjangoWhiteNoise
application = get_wsgi_application()
application = DjangoWhiteNoise(application)
This way nginx site conf is ignored (but I think they had already ignored!)
Django WhiteNoise documentation
With a couple of lines of config WhiteNoise allows your web app to
serve its own static files, making it a self-contained unit that can
be deployed anywhere without relying on nginx, Amazon S3 or any other
external service. (Especially useful on Heroku, OpenShift and other
PaaS providers.)
It’s designed to work nicely with a CDN for high-traffic sites so you
don’t have to sacrifice performance to benefit from simplicity.
WhiteNoise works with any WSGI-compatible app but has some special
auto-configuration features for Django.
WhiteNoise takes care of best-practices for you, for instance:
Serving compressed content (gzip and Brotli formats, handling
Accept-Encoding and Vary headers correctly) Setting far-future cache
headers on content which won’t change Worried that serving static
files with Python is horribly inefficient? Still think you should be
using Amazon S3? Have a look at the Infrequently Asked Questions.
It looks to me like the issue is two-fold:
It looks like you may have an error in your nginx config. Is new_esmart/ really in your root directory/ or is it somewhere like /home/sam/new_esmart/? If it is not in your root directory, make sure to provide the complete path.
It looks like your STATIC_ROOT will point to path/to/new_esmart/static/ rather than /new_esmart/esmart2/static/. Keep in mind that STATIC_ROOT is the place where your static files will be copied to when you run collectstatic not the place you personally place static files when creating them initially.
So what you probably need to do is confirm that you really want your static files collected to /actual/path/to/new_esmart/static/ and then use that same path in your nginx config.
Also, as discussed in the comments, you could try adding listen 8001; to your nginx config:
server {
listen 8001;
server_name 192.168.30.17;
access_log off;
...

Nginx is not serving Django static files

I just configured my first django server for a very basic django-website. I'm using Django 1.4 and Nginx 1.0.14 with supervisor and gunicorn.
The problem is that Nginx is not serving the static files as suposed, but I don't know the why because is my first time using it.
This is the path where really lives my static files:
/home/cristian/envs/santalupe.com/santalupe/santalupe/static
And this is the setting I've in my nginx config file:
# Django admin media.
location /media/ {
autoindex on;
alias /home/cristian/envs/santalupe.com/lib/python2.7/site-packages/django/contrib/admin/static/;
}
# Site media
location /static/ {
autoindex on;
alias /home/cristian/envs/santalupe.com/santalupe/santalupe/static/;
}
Please let me know what I need to do in this case because I have not idea about the real problem.
You aren't serving the admin media from Nginx, just normal media. Try something like:
location /admin/media/ {
# this changes depending on your python version
root /home/cristian/envs/santalupe.com/lib/python2.7/site-packages/django/contrib;
}
Note how there's no trailing slash and the path ends at contrib. I'm using almost exactly this code successfully in production.
Maybe manage.py collectstatic on server help you?
Here is good description on right solution https://docs.djangoproject.com/en/dev/howto/static-files/#serving-static-files-in-production

Running Multiple Sites with Django's Sites Framework through Gunicorn/Nginx

I have a Django based CMS that uses Django's sites framework and Nginx/Apache/mod_wsgi virtual hosts to run a number of websites on different domains. We're assessing other options for a Django stack and have the CMS running with a single site on a new server with Nginx proxying to Gunicorn (gunicorn_django, specifically).
Although this works great for a single site, I'm not sure how to configure Gunicorn for multiple sites. The problem is that with Apache/mod_wsgi, we could set the DJANGO_SETTINGS_MODULE for mod_wsgi to the appropriate site's settings.py
import os, sys
def inflight(filename):
"""
Calculate absolute path to the folder containing "myfile.wsgi", then
append to the PYTHONPATH.
"""
ROOT = ('/').join(os.path.abspath(os.path.dirname(filename)).split('/')[0:-1])
sys.path.append(ROOT)
sys.path.append(os.path.join(ROOT, 'website'))
sys.stdout = sys.stderr
# Each website should have a settings file: /www/mysite.com/website/settings.py
os.environ['DJANGO_SETTINGS_MODULE'] = 'website.settings'
import django.core.handlers.wsgi
return django.core.handlers.wsgi.WSGIHandler()
At the moment I'm thinking that I have to have a different instance of Gunicorn for each virtual host site we run but that seems overkill for the traffic we get to most of our sites.
Does anyone run Gunicorn with Django's sites framework and can give a hint to how it's configured?
I had the same problem and stumbled upon this question in search of the same answer.
I know the question is old and you've probably figured it out by now, but since it might be useful for someone else, here's how I solved it:
You do need to run separate gunicorn processes to make django sites framework work because you can only point a gunicorn instance at one settings.py file. If you're sites don't get much traffic, I'd only create 1 or 2 gunicorn workers per site. (I know, still probably overkill).
Ideally you would want to manage these different processes with something like supervisord to make it easier to manage starting/stoping/restarting your different sites, but I couldn't get it working.
First, start up your gunicorn servers on local host at different ports using the command line. Ex:
gunicorn_django -w 2 -b 127.0.0.1:1000 /path/to/my/django/project/site1_settings.py --daemon
gunicorn_django -w 2 -b 127.0.0.1:1001 /path/to/my/django/project/site2_settings.py --daemon
You now have 2 django sites running on localhost at ports 1000 and 1001 (you can use whatever ports suite you).
Now you need to create two separate nginx server configuration files to point each domain name at it's respective django site.
Ex:
server {
listen 80;
server_name website1.com;
client_max_body_size 4G;
keepalive_timeout 4;
location /media {
root /path/to/my/django/project/media; #this servers your static files
}
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://127.0.0.1:1000; #point to the django site already running on local host
break;
}
}
#add in any additional nginx configuration such as support for 500 errors or proxy apache to server php files etc.
}
Then create a duplicate of the nginx configuration for your 2nd site, but change the server name and the proxy_pass to the values for site 2.
Make sure your server configuration files are included in the main nginx.conf file.
Reload nginx and you should be good to go.
If anyone has an easier/better way to go about this please post it.