Nginx i Varnish – konfiguracja pod magento

5 min czytania

Nginx i Varnish - konfiguracja pod magentoNginx, Varnish – obecnie to najczęściej spotykana para programów znacznie przyspieszającą prace magento.
W tym artykule opiszę konfigurację jaką najczęściej stosujemy w firmie smartmage.pl.
Oczywiście programy muszą być zainstalowane w systmie. Do zainstalowania Nginxa można użyć poleceń:

apt-get install nginx

Do zainstalowania Varnisha musimy dodać dodatkowe repozytoria:

curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -
echo "deb http://repo.varnish-cache.org/debian/ wheezy varnish-3.0" >> /etc/apt/sources.list
apt-get update
apt-get install varnish

Konfiguracja programów: Varnish na porcie 80, Nginx na porcie 8080.

Konfiguracja nginxa na porcie 8080:
Plik nginx.conf:


user www-data;
worker_processes 4; # Liczbę ustawiamy taką samą jak liczba procesorów

pid /var/run/nginx.pid;

events {
 worker_connections 1024;
}

http {
 ##
 # Zabezpieczenie przed atakami DDOS
 ##

 limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=5r/s;
 limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;

 ##
 # Basic Settings
 ##

 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_timeout 65;
 types_hash_max_size 2048;
 server_tokens off;
 client_max_body_size 20m;
 client_body_buffer_size 128k;

 include /etc/nginx/mime.types;
 default_type application/octet-stream;

 ##
 # Logging Settings / Zmiana logowania ip. W standardowej konfiguracje bedzie tylko logowania ip z Varnisha
 ##

 log_format varnish_log '$http_x_forwarded_for - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent "$http_referer" ' '"$http_user_agent"' ;
 access_log /var/log/nginx/access.log;
 error_log /var/log/nginx/error.log;

 ##
 # Gzip Settings
 ##

 gzip on;
 gzip_min_length 1100;
 gzip_buffers 4 32k;
 gzip_disable "msie6";

 gzip_vary on;
 gzip_proxied any;
 gzip_comp_level 9;
 gzip_http_version 1.1;
 gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript applicacion/x-font-ttf;

 ##
 # nginx-naxsi config
 ##
 # Uncomment it if you installed nginx-naxsi
 ##

 #include /etc/nginx/naxsi_core.rules;

 ##
 # Virtual Host Configs
 ##

 include /etc/nginx/conf.d/*.conf;
 include /etc/nginx/sites-enabled/*;
}

Przykladowy plik vhosta:


server {
 listen 10.0.0.10:8080; # Przykładowy ip

 server_name www.domena.pl; ## Domain is here twice so server_name_in_redirect will favour the www
 root /var/www/domena/web;

 location / {
 index index.php index.html; ## Allow a static html file to be shown first
 try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
 expires 30d; ## Assume all files are cachable
 }

 ## These locations downloadable would be hidden by .htaccess normally
 location ^~ /app/ { deny all; }
 location ^~ /includes/ { deny all; }
 location ^~ /lib/ { deny all; }
 location ^~ /media/downloadable/ { deny all; }
 location ^~ /pkginfo/ { deny all; }
 location ^~ /report/config.xml { deny all; }
 location ^~ /var/ { deny all; }

 location /var/export/ { ## Allow admins only to view export folder
 auth_basic "Restricted"; ## Message shown in login window
 auth_basic_user_file htpasswd; ## See /etc/nginx/htpassword
 autoindex on;
 }

 location /. { ## Disable .htaccess and other hidden files
 return 404;
 }

 location @handler { ## Magento uses a common front handler
 rewrite / /index.php;
 }

 location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
 rewrite ^(.*.php)/ $1 last;
 }

 location ~ .php$ { ## Execute PHP scripts
 if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss

 expires off; ## Do not cache dynamic content
 fastcgi_read_timeout 1200s;
 fastcgi_send_timeout 1200s;
 fastcgi_connect_timeout 1200s;
 fastcgi_pass unix:/var/run/php5-fpm.sock;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 fastcgi_param MAGE_RUN_CODE default; ## Store code is defined in administration > Configuration > Manage Stores
 fastcgi_param MAGE_RUN_TYPE store;
 fastcgi_param PHP_ADMIN_VALUE sendmail_path = /usr/sbin/sendmail -t -i -fadres@email.pl;
 include fastcgi_params; ## See /etc/nginx/fastcgi_params

 # Ograniczenie polaczen DDOS
 limit_req zone=req_limit_per_ip burst=10 nodelay;
 limit_conn conn_limit_per_ip 10;
 }

 access_log /var/log/nginx/access-domena.pl.log varnish_log;
 error_log /var/log/nginx/error-domena.pl.log;
}

Konfiguracja Varnisha na porcie 80:

Konfiguracja pliku varnish w katalogu /etc/default:

START=yes

# Maximum number of open files (for ulimit -n)
NFILES=131072

# Maximum locked memory size (for ulimit -l)
# Used for locking the shared memory log in memory. If you increase log size,
# you need to increase this number as well
MEMLOCK=82000

DAEMON_OPTS="-a 10.0.0.10:80 \
 -T localhost:6082 \
 -f /etc/varnish/default.vcl \
 -S /etc/varnish/secret \
 -s malloc,1024m;

Konfiguracja pliku default.vcl w katalogu /etc/varnish:


# default backend definition. Set this to point to your content server.
backend default {
 .host = 10.0.0.10;
 .port = 8080;
}

# admin backend with longer timeout values. Set this to the same IP & port as your default server.
backend admin {
 .host = 10.0.0.10;
 .port = 8080;
 .first_byte_timeout = 18000s;
 .between_bytes_timeout = 18000s;
}

# add your Magento server IP to allow purges from the backend
acl purge {
 10.0.0.10;
 localhost;
 127.0.0.1;
}

import std;

sub vcl_recv {
if (req.restarts == 0) {
 if (req.http.x-forwarded-for) {
 set req.http.X-Forwarded-For =
 req.http.X-Forwarded-For + ", " + client.ip;
 } else {
 set req.http.X-Forwarded-For = client.ip;
 }
 }
if (req.request != "GET" &&
req.request != "HEAD" &&
 req.request != "PUT" &&
 req.request != "POST" &&
 req.request != "TRACE" &&
 req.request != "OPTIONS" &&
 req.request != "DELETE" &&
 req.request != "PURGE") {
 /* Non-RFC2616 or CONNECT which is weird. */
 return (pipe);
 }

# purge request
 if (req.request == "PURGE") {
 if (!client.ip ~ purge) {
 error 405 "Not allowed.";
 }
 ban("obj.http.X-Purge-Host ~ " + req.http.X-Purge-Host + " && obj.http.X-Purge-URL ~ " + req.http.X-Purge-Regex + " && obj.http.Content-Type ~ " + req.http.X-Purge-Content-Type);
 error 200 "Purged.";
 }

# switch to admin backend configuration
 if (req.http.cookie ~ "adminhtml=") {
 set req.backend = admin;
 }

# we only deal with GET and HEAD by default
 if (req.request != "GET" && req.request != "HEAD") {
 return (pass);
 }

# normalize url in case of leading HTTP scheme and domain
 set req.url = regsub(req.url, "^http[s]?://[^/]+", "");

# collect all cookies
 std.collect(req.http.Cookie);

# static files are always cacheable. remove SSL flag and cookie
 if (req.url ~ "^/(media|js|skin)/.*\.(png|jpg|jpeg|gif|css|js|swf|ico)$") {
 unset req.http.Https;
 unset req.http.Cookie;
 }

# not cacheable by default
 if (req.http.Authorization || req.http.Https) {
 return (pass);
 }

# do not cache any page from index files
 if (req.url ~ "^/(index)") {
 return (pass);
 }

# as soon as we have a NO_CACHE cookie pass request
 if (req.http.cookie ~ "NO_CACHE=") {
 return (pass);
 }

# remove Google gclid parameters
 set req.url = regsuball(req.url,"\?gclid=[^&]+$",""); # strips when QS = "?gclid=AAA"
 set req.url = regsuball(req.url,"\?gclid=[^&]+&","?"); # strips when QS = "?gclid=AAA&foo=bar"
 set req.url = regsuball(req.url,"&gclid=[^&]+",""); # strips when QS = "?foo=bar&gclid=AAA" or QS = "?foo=bar&gclid=AAA&bar=baz"

return (lookup);
}

sub vcl_hash {
 hash_data(req.url);
 if (req.http.host) {
 hash_data(req.http.host);
 } else {
 hash_data(server.ip);
 }

if (req.http.cookie ~ "PAGECACHE_ENV=") {
 set req.http.pageCacheEnv = regsub(
 req.http.cookie,
 "(.*)PAGECACHE_ENV=([^;]*)(.*)",
 "\2"
 );
 hash_data(req.http.pageCacheEnv);
 remove req.http.pageCacheEnv;
 }

if (!(req.url ~ "^/(media|js|skin)/.*\.(png|jpg|jpeg|gif|css|js|swf|ico)$")) {
 call design_exception;
 }
 return (hash);
}

sub vcl_fetch {
 if (beresp.status == 500) {
 set beresp.saintmode = 10s;
 return (restart);
 }
 set beresp.grace = 5m;

# enable ESI feature if needed
 if (beresp.http.X-Cache-DoEsi == "1") {
 set beresp.do_esi = true;
 }

# add ban-lurker tags to object
 set beresp.http.X-Purge-URL = req.url;
 set beresp.http.X-Purge-Host = req.http.host;

if (beresp.status == 200 || beresp.status == 301 || beresp.status == 404) {
 if (beresp.http.Content-Type ~ "text/html" || beresp.http.Content-Type ~ "text/xml") {
 if ((beresp.http.Set-Cookie ~ "NO_CACHE=") || (beresp.ttl < 1s)) { set beresp.ttl = 0s; return (hit_for_pass); } # marker for vcl_deliver to reset Age: set beresp.http.magicmarker = "1"; # Don't cache cookies unset beresp.http.set-cookie; } else { # set default TTL value for static content set beresp.ttl = 4h; } return (deliver); } return (hit_for_pass); } sub vcl_deliver { # debug info if (resp.http.X-Cache-Debug) { if (obj.hits > 0) {
 set resp.http.X-Cache = "HIT";
 set resp.http.X-Cache-Hits = obj.hits;
 } else {
 set resp.http.X-Cache = "MISS";
 }
 set resp.http.X-Cache-Expires = resp.http.Expires;
 } else {
 #remove Varnish/proxy header
 remove resp.http.X-Powered-By;
 remove resp.http.X-Varnish;
 remove resp.http.Via;
 remove resp.http.Age;
 remove resp.http.X-Purge-URL;
 remove resp.http.X-Purge-Host;
 }

if (resp.http.magicmarker) {
 # Remove the magic marker
 unset resp.http.magicmarker;

set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
 set resp.http.Pragma = "no-cache";
 set resp.http.Expires = "Mon, 31 Mar 2008 10:00:00 GMT";
 set resp.http.Age = "0";
 }
}

Na koniec restartujemy Nginx-a oraz Varnish-a. System jest gotowy do pracy.

Menu