.htaccess

Най-просто, целта и идеята на .htaccess файла е да оверрайдне определени настройки на Apache на ниво директория, и рекурсивно – на нейните поддиректории. Но за да кажем на Apache да използва даден .htaccess файл, трябва да използваме AllowOverride директивата.

Ако зададем стойността и на All ще разрешим .htaccess да презаписва всички настройки на ниво директория

Ако вместо All изброим дадени директиви, ще зададем, че само те ще бъдат презаписвани от даденият .htaccess.

CGI

Webpage generating programs invoked by server software that operate according to the CGI specification are known as CGI scripts. This specification was quickly adopted and is still supported by all well-known server software, such as ApacheIIS, and (with an extension) node.js based servers.

На практика, всяка програма/скрипт може да бъде CGI софтуер, щом може:
1. да чете от stdin;
2. да пише на stdout;
3. да чете environment променливи от Операционната система и уебсърва;
4. да бъде извиквана от уебсърва.

Идеята на CGI е да бъде стандарт, задаващ как информцията постъпила от клиента към уебсървъра, да бъде предадена към външна програма, която да я обработи, и да я върне на уебсървъра, който да я върне на клиента.

Защо? Защото вече почти винаги, не е достатъчно уебсърва просто да върне някаква статична информация, а трябва да извика допълнителен софтуер, бил той скрипт или компилирана програма, която да свърши доста друга работа, като например – работа с бази данни, комуникация с други сървъри и т.н….

Демек, „мостът“ между уебсърва и скрипта (PHP, Perl…), който най-често (но не задължително) е на сърва, обработващ HTTP заявката.

Затова се говори за общ интерфейс или стандарт. За да могат различни езици за програмиране да работят по унифициран начин с уебсърва, спазвайки този стандарт.

Initially, different server software would use different ways to exchange this information with scripts. As a result, it wasn’t possible to write scripts that would work unmodified for different server software, even though the information being exchanged was the same. Therefore, it was decided to specify a way for exchanging this information: CGI (the Common Gateway Interface, as it defines a common way for server software to interface with scripts). Webpage generating programs invoked by server software that operate according to the CGI specification are known as CGI scripts.

За да може една програма да бъде използвана като CGI програма, трябва да може да чете от стандартният input (stdin), да пише на стандартният output (stdout), и да може да достъпва environment variables на сървъра.

Такава програма може да бъде както скриптове, така и компилирани, изпълними файлове.

CGI Задълженията на уебсърва са:
  • когато уебсърва получи HTTP заявка, той има две възможности – или директно да върне поисканият ресурс, или да извика даденият скрипт/изпълним файл, който да обработи заявката и да върне HTTP резултатът си на уебсърва, който да върне на клиента HTTP респонсът.
  • във вторият случай – да стартира поисканият в рекуста скрипт/изпълним файл.
  • кое от двете да се случи, зависи от конфигурации на уебсърва, с които му казваш „филета с такова разширение – викай този скрипт/изпълним файл…. филета с такова разширение – такъв….“ Демек, по разширение се определя кой да обработи даденият HTTP рекуест.
    Не точно!
    Общата конвенция е, че CGI изпълним файл трябва да е в cgi-bin директорията. По конвенция – всичко що е там трябва да е изпълним файл и се приема за т.н. CGI script.
    A common convention is to have a cgi-bin/ directory at the base of the directory tree and treat all executable files within this directory (and no other, for security) as CGI scripts.
  • да му предаде данните от HTTP заявките (хедъри и бодито)
  • да получи готовият HTTP response (response code, хедъри и бодито) и да го върне на клиента. Което повдига логичният въпрос – ОК, когато скрипт/изпълним файл обработва HTTP заявката, той трябва да зададе response хедърите. Но ако е статичен контент, и няма нужда от гореспоменатите, значи уебсърва отговаря освен разбира се за бодито, така и за responsе хедърите.
един пример

Имаме клиент, който отправя HTTP заявка към сърва, тази заявка по стандарт съдържа т.н. request line, напр. POST /path/to/something HTTP/1.1 , който както се вижда показва HTTP методът, URI-ят и версията на HTTP протоколът.

Добре, но даденият URI показва скриптът/програмата, която да го обработи. Следователно, тя трябва да бъде извикана, както и информацията от HTTP рекуестът трябва да и бъде предадена – хедъри, самите данни…

Уебсървърът… той е просто казано един „портиер“, идват люде при него, този за това, онзи за онова… и той им извиква съответният софтуер, който да ги обслужи. И начинът на викане на съответният софтуер, както и предаването на информацията от даденият човек, към даденият софтуер, това е идеята на CGI.

Портиер, но от малко по-горна категория. Демек, да база това какво точно иска даденият човек като услуга, той вика съответният софтуер, като му предава и документите, които човекът носи със себе си. Демек, не просто „Идете на етаж втори, кабинет 230“, а по-скоро „Искате разрешително за еди какво си, дайте ми бумагите и папките си, аз ей сега ще извикам Иван Иванов от етаж втори, кабинет 230, ще му дам Вашите папки и бумаги, и той ще има грижата като ми върне готовото разрешително, аз да Ви го върна на Вас“.
Нали съм все пак уебсърв… така де… портиер…

E, ако е нещо статично и няма нужда да се вика някой като Иван Иванов, и портиерът може сам да ви помогоне, той ще го направи.

The web server then launches the CGI script in a new computer process, passing the form data to it. The output of the CGI script, usually in the form of HTML, is returned by the script to the Web server, and the server relays it back to the browser as its response to the browser’s request.

Отделно, да не забравяме, че „Иван Иванов“ трябва да върне и служебна информация, под формата на HTTP хедъри, като например, това което връща какъв тип документ е и т.н…
…upon returning, the script must provide all the information required by HTTP for a response to the request: the HTTP status of the request, the document content (if available), the document type (e.g. HTML, PDF, or plain text), et cetera.

Как става самото предаване на HTTP заявката, получена от уебсърва, към CGI софтуера?

Чрез сетване на стойности на т.н. environmet variables.

Демек:
For instance, if a slash and additional directory name(s) are appended to the URL immediately after the name of the script (in this example, /with/additional/path), then that path is stored in the PATH_INFO environment variable before the script is called.
Ето, имаме вече една environment variable сетната със стойност…

Ако имаме query string в URI-я, тогава ще имаме друга environment variable – QUERY_STRING, която ще съдържа всичко от URI след „?“.
Демек, ако имаме URL: http://localhost/i.php?asd=123&qwe=456
QUERY_STRING ще е asd=123&qwe=456
ПРЕДИ СКРИПТЪТ/ИЗПЪЛНИМИЯТ ФАЙЛ да бъде стартиран.

Демек, първо се сетват environment променливите, после се стартира каквото трябва, иначе не би било логично.

Какво са т.н. „environment variables“? Променливи, действащи от страна на компютъра или средата, в която работи даденият процес. Това са применливи-настройки, с които операционната система да зададе определени стойност на даденият процес.

Друго важно за „environment vars“ е , че уебсърва ДОБАВЯ свои към общият брой от тях, а не ги СЪЗДАВА от нищото. Демек, Операционната система си има и доста свои, и без уебсърва.
Some, but not all, of these variables are defined by the CGI standard. Some, such as PATH_INFOQUERY_STRING, and the ones starting with HTTP_, pass information along from the HTTP request.

Има две основни групи env променливи, които са предавани на CGI – server specific и request specific.

CGI, FastCGI и SAPI

CGI – когато уебсървърът получи заявка, стартира даденият CGI софтуер (PHP, Perl, изпълним файл…), който се унищожава след като си свърши работата.

В случаят с PHP, при всяка постъпила HTTP заявка, уебсърва знае кой изпълним файл (напр. EXE ако сме под Windows) да стартира, и да му подаде PHP скрипта, който той да интерпретира и изпълни. И да очаква резултатът, който съответно да върне на клиента.

Това е бавно, защото е свързано всеки път с четене и парсиране на конфиг файлове, зареждане на модули… Oтделно, колкото такива процеси имаме, толкова пъти това се повтаря и за всеки процес, всичко това „яде“ памет и CPU…
For a high number of HTTP requests, the resulting workload can quickly overwhelm the Web server.

Е, има и предимства. Всяка HTTP заявка е отделна за себе си, отделен процес. Стартира се, изпълнява каквото изпълнява, унищожава се и толкоз… Няма как една от тях да счупи останалите.

SAPI – тук CGI програмата е всъщност модул на уебсървъра, който добавя функционалност към него (уебсърва).
За което уебсървът трябва съответно да предостави определен интерфейс, с който да „позволи“ не само на PHP, но и на други модули да сторят това – да се интегрират към него (уебсърва), и да го „разширят“ с функционалности.

Печели се многократно повече скорост, най-малкото защото гореспоменатите действия, като парсиране на конфиг файлове, зареждане на модули и т.н… се случват еднократно, по време на стартиране на уебсървъра. Всякакви INI-та се парсват и зареждат веднъж и траят докато работи уебсърва.

Недостатък е например, че ако се срине даденият модул (PHP в нашият случай), това може да срине целият уебсърв.

Също, трябва ли да промениш някакви настройки – трябва рестарт на уебсърва.

Също, даденият моду, в нашият случай PHP, ще работи с правата на уебсърва, примерно Apache, Nginx… бидейки негов модул, което може да създаде определини проблеми с правата на ниво Операционна система.

FastCGI – тук имаме нещо като подобрена версия на CGI като разликите със CGI са следните:

  1. уебсървърът не комуникира директно с CGI програмата, а използва за посредник FastCGI модул, който модул от своя страна стартира и комуникира посредством TCP с определен брой CGI програми, които могат и да не са на същята уебсървър;
  2. CGI програмите не се унищожават, след като заявката е обслужена, а остават работещи за да чакат други заявки;
  3. След като CGI програмите може и да не са на същата машина, пърформанс скейлването би било много по-лесно.

Литература:

https://fuzzytolerance.info/blog/2006/09/13/2006-09-13-cgi-vs-sapi-vs-fastcgi/

Apache reload vs. restart

Reload казва на сърва да презареди конфиг файловете, което за някои от детските сървиси може и да не е възможно. Което налага да се използва restart за по-сигурно. Демек, някои процеси няма да релоуднат конфиговете, затова ако не е проблем, за по-сигурно – рестартни.

restart = stop + start

reload = remain running + re-read config files

Има два вида рестарт – normal restart и graceful restart

Normal restart – убий детските процеси, дори и да работят и „роди“ нови.
apachectl -k stop/start/restart

Graceful restart – изчакай детските процеси да си свършат работата и тогава да умрат. Новите родени вече ще са с новите конфигурации.
apachectl -k graceful

Graceful си е пак подобен на Normal restart, просто не дърпа шалтера веднага, а изчаква децата да си свършат работата и тогава им дърпа шалтера.

DNS A and CNAME records

A тип DNS запис имаме когато на конкретен IP адрес съответства конкретен сървър, например ако изпълните
dig A primetech.bg
получавате
primetech.bg. 1735 IN A 217.174.156.170

тук 1735 е TTL в секунди – this is the amount of time the record is allowed to be cached by a resolver. Най-вероятно, колко секунди клиентът може да смята, че няма промяна на IP-то на този хост.

А типовете са най елементарни, те просто „вързват“ IP с хост.

Може да имате много хоста вързани към едно IP

https://support.dnsimple.com/articles/a-record/

CNAME – Canonical Name Record or Alias Record – задава, че даденият хост е всъщност alias на друг хост.

Използва се например за поддомейни – главният домейн стои зад А record, но www.*, mail.*, static.*… стоят за CNAME record.

Голямото предимство тук е, че ако променим IP-то на главния домейн, няма да има нужда да променяме IP-тата на отделните поддомейни, защото те стоят зад главния, а не зад IP.

https://www.pickaweb.co.uk/kb/cname-can-use-domain/

FQDN

An FQDN, or a Fully Qualified Domain Name е абсолютният адрес на дадена машина в дадена мрежа. Подчертавам „абсолютният“.
Демек: всяка машина си има свое име, но и всяка машина е част от дадена мрежа.

Следователно, FQDN-a на дадената машина, е цялата комбинация от:
името на машината, на машината над нея, на машината над нея, на машината над нея… и TLD-то накрая.

Демек, аз съм Пламен.
И FQDN-ът ми би бил:
Пламен.Русе.България.Земя.Слънчева система.Млечен Път.com

Всичко, което категорично определя дадена машина в дадена мрежа.

A fully qualified domain name is always written in this format:
[host name].[domain].[tld].

An FQDN might also be called an absolute domain name since it provides the absolute path of the host.

Съответно има и термин PQDN (Partially Qualified Domain Name)

Reverse proxy

Forward proxy е прокси сървър, през който минават твоите заявки КЪМ интенет, преди да излизат от локалната ти мрежа. То е „при теб“, или поне – между теб и интернет.

Reverse proxy е подобно, но то е след като заявката ти мине през интернет и тъкмо преди да стигне до сървъра, към който е тя.

Reverse proxy е „от другата страна на интернет“, Forward proxy е от „твоята страна“.

С FP можеш ти да се скриеш зад проксито.

С RP – отсрещният сървър може да се скрие за него.

FP e между теб (клиентът) и интернет.

RP е между интернет и сървърът.

В предишна фирма имахме проект за заобикаляне на АдБлокер? Слагахме директиви в httpd.conf на Апача на сайта, И когато не се намираше картинка (404) – прави интърнал редирект с RewriteRule към друг сървър, който да сервира картинката, но вече не картинка, а рекламно банерче. Демек, в този случай, сърва на сайта, започва да играе ролята на Reverse Proxy, даже и без някой да осъзнава. Reverse proxy, което прихваща и обработва ненамерените картинки.

Демек, reverse proxy e философия, самият „чалъм“, може и да не е някаква физическа машина или отделна програма.

„А reverse proxy is a type of proxy server that retrieves resources on behalf of a client from one or more servers.“

От името на клиента. Защо? Защото стои между клиента и сървъра и сървъра на практика не вижда клиента, вижда това RP.

„Contrary to a forward proxy, which is an intermediary for its associated clients to contact any server, a reverse proxy is an intermediary for its associated servers to be contacted by any client.“ – все посредници, само че едното е посредник на клиента, другото – на сървъра, от другата страна.

„These resources are then returned to the client as if they originated from the Web server itself.“

Така ставаше при Проектът Х – тези неоткрити (404) картинки, сърва на сайта ги сервираше на клиента с интърнал редирект от сърва на Проектът Х.

И клиентът си мислеше, че е са от сърва на сайта.

Все едно, отиваш в магазин, питаш за „мляко от зелено, марсианско пиле“.
Естествено продавачът не е и чувал за такова нещо, но ти казва „Да, имаме, един момент“, и докато те омайва, продавачката му отива до съседният магазин, където имат мляко от зелено, марсианско пиле, носи го, тайно, без ти да разбереш, „под масата“, го дава на продавача, и той ти казва: „Ето заповядайте“. Колко е мляко от зелено, марсианско пиле или рекламно банерче, както при Проектът Х, е друг въпрос. Въпросът е, че ти си мислиш, че е от този магазин, и че е.

Ето как в този случай, този продавач, който е всъщност истинският сърв на сайта, действа като Reverse Proxy – заблуждава те, че той ти сервира стоката, а всъщност я е взел от друг продавач (сърв), без ти да разбереш.

Разни продавачки, дето бягат по улицата между магазините, носейки кутии с обувки например, какви са? Точно едни Reverse Proxy-та. Забаламосват те с „момент, да проверим в склада дали има този номер…“, а колежката вече търчи до съседния магазин.

Aпаче vs. Нгинкс

В общи линии, Апача е по-мощен откъм функционалност и гъвкавост за настройка, следователно е по-добър и подходящ за general purposes. Но по-лош за голям и едновременен “напън” при неподходяща настройка.

Nginx-а е по-дървен, но по-бърз и подходящ за статичен контент, по-добре разпределя задачите си при голямо натоварване.

Апача е “швейцарско ножче”, Nginx e кирка, лопата или мотика.
“Швейцарско ножче” обаче, към което може много по-лесно да добавиш например лупа, огледалце, трионче… отколкото от кирката или мотиката да направиш… миксер.

Напълно могат да се заместват и допълват един друг, но вече въпросът е във взаимното допълване на предимствата и недостатъците на двата – за да се получи “добре изпилена и смазана система”.

Така че, няма отговор на въпроса: “кой е по-добър”.
По-добър, за какво?
Истината е в допълването, в заедността.

Погледнато от историческа гледна точка, Апача (1995) е по-стар от Nginx-a, (2002). Какво е бил Интернет в 1995, в сравнение с 2002 г.? Реторичен въпрос, нали? Или какво е сега, в сравнение с 2002г.?
Апача генерално не е правен за голям “напън”, не че не държи на голям напън при правилна настройка, просто Nginx-a е правен първо с тази идея, и поне за това е по-добър. Подчертавам на ПОНЕ.

Nginx е създаден за да реши т.н. “C10k problem”, което може да се представи нагледно със следната ситуация:
Лелка на гише, например в банка или в някаква институция.
Изсипват и се едновремнно N на брой клиенти, тя се шашва и казва: “О не, не мога да ви оправя всички наведнъж, я се наредете един след друг, така наведнъж не мога да ви обслужа.” Подчертавам на “ЕДИН СЛЕД ДРУГ”.

Connection Handling Architecture
MPM, демек Multi Processing Module – демек, текущо зареденият модул на Апача, който отговяря за разпределянето на задачите (that dictate how client requests are handled).
Биват три: mpm_prefork, mpm_worker и mpm_event

За да разберем разликите между тях, трябва първо и задължително, да разберем разликите межд process и thread.

Представям си го нагледно и практично така:
Процесът е по-общото, тредът е процес, разделен на части.
Все едно процесът е фирма с шеф, който събира служителите и им  казва “Трябва да се свърши едикакво си”. Иване – ти поеми това, Петре – ти свърши онова, Мария – ти ще отговаряш за това… Имате фирмените ресурси, които ви трябват – баничарката, принтера и ксерокса, някой лев за командировъчни…”
Това са т.н. “споделени ресурси”. Тредовете-служители могат да ги ползват, стига да не си пречат и застъпват, защото те (ресурсите) са на ниво – процес-фирма.
Вътре в процеса-фирма, всички ресурси са споделени между ресурсите-тредове. Нали шефът е един все пак. Но между отделните процеси-фирми – не.
Не може “Дезинфекционна станция Трепем гад всякаква” ООД и неговете служители-тредове, да ползват баничарката или ксерокса на “Топли мекици” ООД.

mpm_prefork – един рекуест – един процес – един тред.
Рекуестът нека е клиент на фирма. Процесът нека е шефът на фирмата. Тредът нека е служителят (служителите). А над шефовете (процесите) и техните тредове (служители) бди неотклонно core-то (ядрото) на Апача.

Идва рекуест (демек клиент) при Коре-то и иска да му се свърши някаква работа. Коре-то му създава фирма (демек шеф), която да му свърши работата, и тази фирма (шеф) ще има ЕДИН тред (служител), който реално ще свърши работата. Демек – един рекуест – един процес – един тред.
Един клиент – една фирма(шеф) – с един служител.
Който служител ще има всички ресурси на фирмата, няма да се чака и занимава с колеги-идиоти, няма “дай баничарката, че ми трябва”, няма “Мише, кога ще ми издадеш едикойси документ”… Това, че е сам служител на шефа си, не значи, че не може да ползва всички ресурси на фирмата, без да се съобразява с колегите си. И не значи, че няма да свърши работата даже по-бързо от ако бяха много колеги (тредове) и работата не беше разпределна между тях.

Лошото е ,че не се оплътняват ресурсите много добре. Демек, шефът дава целите ресурси на фирмата на единственият си служител-тред, което не значи, че този служител-тред ще скатава или краде от бензина на баничарката. Идеята е ,че фирмата-процесът като си има запазени ресурси, те остават блокирани само за тази фирма, и са недостъпни за останалите фирми, дори и да са свободни. Демек, фирмената баничарка, фирмената секретарка… са си само за дадената фирма. Ако друга фирма и трябва баничарка или секретарка – да си купи (запази в паметта) своя.

Обаче когато рекуестите станат повече от процесите, производителнността спада рязко. Не знам защо, явно просто няма процес, който да обработи новопостъпилият рекуест? И к’о прай’м? Сядаме и чекаме? Демек, Коре-то казва на клиента “Нема свободна фирма да Ви свърши работата, е па че почекате”.

Затова mpm_prefork е сигурен откъм споделени ресурси (колегите-тредове) няма да се чакат и бъркат един друг за ресурси, но пък е неефективен при “напън” от рекуести-клиенти.

Докато има процеси (шефове) колкото за всеки рекуест (клиенти) – всичко е ОК. И понеже имаме “един процес – един тред” – значи това е модулът, подходящ за “non thread safe” PHP – понеже процесите си имат запазена, своя памет, няма как да се оплетат тредовете. Нали е един тред само в процеса.

mpm_worker – Тук пак като дойде клиент-рекуест, core-то вместо да създава отделна фирма с един служител, както при mpm_prefork (и по този начин да гарантира, че отделните служители-тредове няма да се чакат и пречат), създава един процес-фирма с много тредове-служители, на които се дава даден рекуест-клиент, и той (служител-треда) си го движи. Колко фирми-процеса и всяка с по колко треда-служителя във всяка ще има – не знам.
Но тук със сигурност има доста по-голямо уплътняване на общият ресурс.
Нека осъзнаем, че както и в живота, процесите-фирми само управляват тредовете-служители, работата се върши от тредовете-служители. Демек, колкото повече процеси-фирми – толкова “повече вожд, малко индианец”. Е да, разделението и сигурността откъм оплитане на ресурси е по-голяма, вярно.

mpm_event – този модул е същият като mpm_worker но се различава по начина, по който обработва keep-alive рекеуест-клиентите. Тоест: mpm_worker ще държи тред-служителя, докато keep-alive е в сила, дори и работата да е свършена. mpm_event отделя служител-тредовете за активните клиент-рекуести отделно от тези за keep-alive. The event MPM handles keep alive connections by setting aside dedicated threads for handling keep alive connections and passing active requests off to other threads. Идеята е явно, да не се задръсти сървъра с “Чакай да се наканя…” клиенти.

Както се вижда, Апача е доста по-гъвкав откъм това, какъв начин на обслужване на заявките генерално ще изберете.

Distributed vs Centralized Configuration
Nginx does not interpret .htaccess files, nor does it provide any mechanism for evaluating per-directory configuration outside of the main configuration file. This may be less flexible than the Apache model, but it does have its own advantages.

Apache има възможност за настройки на ниво директория (per directory basis) с помощта на .htaccess

Nginx – не.

Nginx печели производителност, защото не трябва да отваря, чете, обработва и т.н… този .htaccess файл за всеки рекуест, както Apache, но пък губи гъвкавост. Също имай предвид, че Apache прави това “отваряне, четене, обработване…” става по целия път от корена – до даденият ресурс (файл), и застъпващите се директиви се override-ват… и изобщо…

При Nginx като стартираш с дадени настройки – това е, каквото си настроил – настроил, газ на педалите.

Е да, в Апача може да изключиш .htaccess и би трябвало горните грижи и тревоги да отпаднат, не знам, предполагам…

Modules
При Апача, имаш ядро и модули, и можеш динамично, само с един рестарт да ги активираш/деактивираш.

При Nginx пак имаш разни модули, но трябва да компилираш. In Nginx, modules are not dynamically loadable, so they must be selected and compiled into the core software.

File vs URI-Based Interpretation
Или с други думи, като как двата сърва интерпретират заявените URI ресурси и ги мапват към съответните ресурси (най-често – филета).

По подразбиране, и двата сърва приемат заявените ресурси като ресурси на файловата система. Вземат домейна, заметват го с document root-a, и от там нататък – следва пътя до ресурса.

Апача може и по двата начина – демек, може да интерпретира заявените ресурси и буквално като филета или директории,
или като “псевдоними” на реални филета и директории.
Има разни механизми, дали ще е с RewriteRules или с директиви в htconfig – a…

Nginx-a може само по един начин – като интерпретира URI-то като път до ресурса на файловата система.

Static vs Dynamic Content
Апача обработва ПХП като

  1. или ПХП-то му е инсталирано като модул (т.н. “dynamically loadable modules”), да си припомним все пак, че Апача по принцип е набор, или по-грубо казано – “купчина” от модули, обединени от ярдо.
  2. или като вика външен интерпретатор (интерпретатора на ПХП).

Това като цяло явно е с идеята да може като интерпретатор да се ползва не само ПХП но и други езици. Да е по-модулно.

Nginx-a няма подобен механизъм за “външно обработване” на скриптове. Там трябва да се настрои комуникация между Nginx-а и скрипта, като се използва някакъв протокол (http, FastCGI, SCGI, uWSGI, memcache).

И тук идва допълнителното усложнение – излиза, че всеки рекуест за ПХП страница води до допълнителен “вътрешен” рекуест от Nginx-a – към ПХП-то.

Конфигурацията изглежда горе – долу така:

location / {
    fastcgi_pass localhost:9000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param QUERY_STRING $query_string;
}

Е да, вярно, този сценарий ще се случи само за динамичен контент. Освен ако под горните редове, ще добавим и тези:

location ~ \.(gif|jpg|png)$ {
    root /data/images;
}

с които ще кажем на Nginx-a да минава през ПХП-то за всичко, без gif, jpg и png