📜 ⬆️ ⬇️

Experience setting up nginx on debian

Yesterday evening I devoted a fuss with the nginx http server as a front-end to apache. As you know, nginx is a lightweight reliable HTTP server written by Igor Sysoev (an employee of Rambler ). It is great for issuing static pages, especially under load. Usually, the nginx + apache bundle is configured, in which nginx serves all incoming requests to the server, gives static files on its own, and requests dynamic content to apache to apache.

So, there are a lot of articles in the Internet on setting up the work of this couple, including in Russian, and there is no point in writing about it. And I will tell you better about the nuances that I encountered yesterday when setting up nginx to work in the right mode, and at the same time I will show and comment on my configuration of this server.


My configuration


For a start, what was actually required to be done? The server was configured for Habrometer . He had to produce statics (logo and css) and dynamics (the actual pages of the site and png-habrometers). At the same time, it was necessary to take into account that the habrometer is created on the fly if it is not in the cache (and the cache is cleaned every 2 hours when new data is requested). Site pages also need to be cached. That was the task.
')
The implementation was decided to do as follows. nginx when processing a request must follow the following rules:
  1. If static is requested, then just return it (all static in stuff stuff).
  2. If a site page is requested, you need to check the cache; if the file is not found in the cache, send the request to the apache backend. The page cache should be cleaned with a given frequency (for different pages the frequency is different).
  3. If the informer is requested, then you need to check the cache for the presence of a file. If the file is not there, send a request to the backend.

The file system is selected for caching habrometers. All generated informers are added to the / image_cache / directory and it is cleaned every 2 hours when the source data is updated. Informers are drawn and put into this directory by a PHP script with the corresponding request.

Memcache is selected for caching site pages. it is easy and convenient to work with it (from both nginx and PHP) and it can clean the cached pages itself after a specified time interval, which cannot be done by the FS without additional scripts. Yes, and memcache will work faster, because All good is stored in the RAM.

The result was the following server configuration:

# cat /etc/nginx/nginx.conf
  user www-data;
 worker_processes 4;
 error_log /var/log/nginx/error.log;
 pid /var/run/nginx.pid;
 events {
     worker_connections 1024;
 }
 http {
     include /etc/nginx/mime.types;
     default_type application / octet-stream;
     access_log /var/log/nginx/access.log;
     sendfile on;
     keepalive_timeout 65;
     tcp_nodelay on;
     gzip on;
     add_header Habrometr "hacker_mode_enabled;)";
     server {
         listen 80;
         server_name habrometr.server.valera.ws habrometr.ru www.habrometr.ru;
         access_log /var/log/nginx/habrometr.access.log;
         location / {
             root / home / habrometr / public_html;
             index index.html index.htm;
             if (-f $ document_root / image_cache $ {uri}) {
                 rewrite ^. * $ / image_cache / $ uri last;
                 break;
             }

             set $ memcached_key "habrometr $ uri";
             memcached_pass localhost: 11211;
             # if a resource is not found in memcached, send a request for Apache
             error_page 404 502 504 = @backend;
             add_header Content-Type "text / html; charset = UTF-8";
             gzip on;
             gzip_proxied any;
             gzip_types application / octet-stream;
     }

     location @backend {
         set $ proxy_uri http://habrometr.ru:99999$request_uri;
         proxy_pass $ proxy_uri;
         proxy_redirect off;
         proxy_set_header X-Real-IP $ remote_addr;
         proxy_set_header X_Forwarded-For $ proxy_add_x_forwarded_for;
         proxy_connect_timeout 20;
     }
     location / image_cache / {
         root / home / habrometr / public_html;
         expires modified + 2h;  # cache expires 2 hours after file modification
     }
     location / stuff / {
         root / home / habrometr / public_html;
         expires 30d;
     }
     location ~ /\.ht {
         deny all;
     }
 } 

Given the above scenario, the entire configuration should be clear. I note only that habrometr.ru : 99999 is apache, to which requests will be redirected. The port I, of course, changed, in reality, usually use 8080 or something like that.

Tricks


And now that is non-trivial in this configuration (at least for a beginner in this field).

Version


First, the server works for me on Debian 4.0. I naturally installed all software from standard repositories. Put from there and nginx. Installed nginx turned out to be version 0.4 with the latest version 0.7 available with a significant list of changes .

It turned out that version 0.4 does not know how to do a lot of what was needed. In particular:
  1. The modified flag does not narrow down for the expire directive, but I needed this to indicate the expiration time of the informer cache (2 hours after creation: expire modified + 2h);
  2. proxy_pass did not know how to use variables, but I needed this opportunity;
  3. memcached did not use the $ memcached_key variable to determine the key, i.e. it was impossible to set the key of the desired format.

In principle, all these problems could be solved by circumventing perverted ways, but I didn’t want to do this at all, so I just installed a fresh version of raw nginx. Fortunately, this is done very simply.

Before describing the installation process, I note that by default, when building from source, all nginx files are put into the / usr / local / nginx directory. Of course, you can change it (--prefix =). But note that installed from nginx packages scatters its files to the appropriate system directories (/ etc, / var, log, / var / run, etc.), which I definitely like more than / usr / local / nginx / *. That's why I compiled nginx from raw files with settings for system directories, and then instead of make install I just manually replaced the old server binary in the / usr / sbin directory with a new one (/ usr / sbin / nginx). There are no more significant files after the build for the server. The config, naturally, remains the same.

So, installing nginx on Debian etch from source over the installed package of the old version.
  # wget http://sysoev.ru/nginx/nginx-0.7.31.tar.gz
 # tar xzf nginx-0.7.31.tar.gz
 # cd nginx-0.7.31
 # apt-get install libpcre3 libpcre3-dev libpcrecpp0
 # /etc/init.d/nginx stop;
 # ./configure --sbin-path = / usr / local / sbin --with-http_ssl_module
 --without-mail_pop3_module --without-mail_imap_module
 --without-mail_smtp_module --prefix = / var / lib / nginx
 --sbin-path = / usr / sbin --conf-path = / etc / nginx /
 --error-log-path = / var / log / nginx --http-log-path = / var / log / nginx
 --pid-path = / var / run --lock-path = / var / lock
 # cd objs
 # cp -f ./nginx / usr / sbin
 # /etc/init.d/nginx start; 

After that, a fresh nginx server should be launched and serve requests, which can do all the things we need.

Documents from memcached


When nginx gives files directly, it passes the Content-type header according to the type of this file. When nginx proxies apache, the content type comes from apache. But when nginx picks up a document from memcached, the Content-type is not set. So, the default is used. And we default on the default_type application / octet-stream ;, and rightly so. In this case, when retrieving a document from the cache, the type will be incorrectly transmitted, and some browsers will offer to save the binary file instead of opening the HTML page. To remedy the situation, in case of return from memcached, we set headers (and, by the way, compression, too) in addition:
  set $ memcached_key "habrometr $ uri";
 memcached_pass localhost: 11211;
 error_page 404 502 504 = @backend;
 add_header Content-Type "text / html; charset = UTF-8";
 gzip on;
 gzip_proxied any;
 gzip_types application / octet-stream; 

At the same time from memcached we get only HTML in UTF-8.

Flies separately, cutlets separately.


As a separate magic, I would like to single out the very method of allocating habrometers by file name and serving them in a special way. In the location / section, select these files:
  if (-f $ document_root / image_cache $ {uri}) {
     rewrite ^. * $ / image_cache / $ uri last;
     break;
 } 

If we find the file in the cache, then we simply return it to the user, informing that the file can be cached before the next update (modification of the file + 2 hours):
  location / image_cache / {
     root / home / habrometr / public_html;
     expires modified + 2h;
 } 

Note the presence of the rewrite last flag and the break directive; for her. Without the use of these two directives, I could not force nginx 0.4 (I did not check it with 0.7) immediately go to the location / image_cache / section, i.e. after finding the file, he proceeded to skip, which is incorrect.

Source: https://habr.com/ru/post/50317/


All Articles