6

Apache is installed and is used to serve mostly Django/Python content. I want to install nginx to serve static content. How to do it and what is a good configuration.

I am on Ubuntu and Apache was installed via apt-get.

2 Answers 2

5
  1. first option: do you have few ip addreses? bind apache to one of them, nginx to another.

    in debian world

    for apache in /etc/apache2/ports.conf include:

    Listen 1.1.2.3:80
    

    in vhost file in /etc/apache2/sites-enabled change:

    NameVirtualHost 1.1.2.3:80; 
    <VirtualHost 1.1.2.3:80>
    ..
    <VirtualHost/>
    

    for nginx in /etc/nginx/sites-enabled/ add:

    listen 1.1.2.4:80
    
  2. second option: move apache to listen on different port [ files as above. tell apache to listen on 127.0.0.1:8080 for instance ] and instruct nginx to reverse-proxy dynamic traffic to your apache while serving /static/ by nginx - for instance:

    server {
     listen   1.1.2.3:80;
     server_name  some.name another.dname;
    
     access_log  /var/log/nginx/something-access.log;
    
     location / {
      proxy_pass http://localhost:8080;
      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;
     }
     location ~* ^.+\.(jpg|js|jpeg|png)$ {
      root /some/where/on/your/disks;
     }
    
    ; put your static hosting config here.
    }
    

btw - think about putting static content on another domain. this should improve end-user speed a little.

0
4

There are many variations on how to accomplish this. I prefer to have one application dedicated to deciding on which server handles what kind of content, while the back end servers simply serve the files they've been requested.

To that end, I employ the Varnish reverse proxy on the front end, listening on port 80. Behind that, I have Apache (port 8880) and nginx (port 8881), both configured for the same domains and pointing to the same directory structure. In my Varnish config file, I have something like this:

backend apache {
  .host = "192.168.0.2";
  .port = "8880";
}
backend nginx {
  .host = "192.168.0.2";
  .port = "8881";
}

[...]

if (req.url ~ "\.(png|gif|jpg|ico|html|htm|js|css|txt)$") {
  set req.backend = nginx;
} else {
  set req.backend = apache;
}

Of course, there's a little more to it, but you get the idea.

Since you already have Apache and nginx installed, you may want to browse this link, which describes a very simliar situation to yours, but uses nginx as the front end for static content and then passes on requests to Apache.

If you want to go really simple, you could simply use a reverse caching proxy (such as Varnish or nginx) in front of Apache. What it will do is cache requests to quickly serve them out to clients, while at the same time relieving the web server itself from serving identical requests. This, by its very nature, will give the same effect as what you're asking for. Since static pages and images rarely change, they will be almost always cached by the front end, whereas dynamic pages will be detected as such and always passed on to the back end.

2
  • Interesting. One comment though… Why would you need Varnish as a reverse proxy, if you already have Nginx? I know that this answer is pretty dated, so maybe at that time, Nging was not that strong as a reverse proxy…?
    – cedbeu
    Oct 3, 2018 at 4:56
  • Given that varnish (at the time of writing) does not receive ssl connection, it does not seem the proper tool for the job. One would have to use nginx anyway to receive the ssl connection, then send it to varnish, which will then distribute.
    – Dominic108
    Feb 24, 2019 at 0:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.