Часть запроса не включена при соответствии URL RewriteRule посмотрите эту часть документов:
Что подобрано?
Шаблон будет первоначально подобран против части URL после имени хоста и порта, и перед строкой запроса. Если Вы хотите соответствовать против имени хоста, порта или строки запроса, используйте RewriteCond с % {HTTP_HOST}, % {SERVER_PORT} или % {QUERY_STRING} переменные соответственно.
Как предложено документами, можно использовать выражение RewriteCond для соответствия на %{QUERY_STRING}
:
RewriteCond %{QUERY_STRING} ^option=com_rsform&Itemid=8&lang=en$
RewriteRule ^index.php$ http://www.index.php
Обратите внимание, что это только работает, когда строка запроса является точно той, Вы соответствуете. Эквивалентная строка запроса, в которой порядок аргументов изменяется, f.i. option=com_rsform&lang=en&Itemid=8
, не будет подобран. Так в этом случае я думаю, что Вы были бы лучше, чтобы отправить все запросы к Вашему Сценарию PHP и иметь тот взгляд на $_GET
и решите, передать ли или нет.
Одно решение состоит в том, чтобы добавить, что дополнительные php-fpm экземпляры Вашему докеру - составляют файл и затем используют nginx в восходящем направлении, как упомянуто в других ответах на баланс загрузки между ними. Это сделано в этом докере в качестве примера - составляют repo: https://github.com/iamyojimbo/docker-nginx-php-fpm/blob/master/nginx/nginx.conf#L137
upstream php {
#If there's no directive here, then use round_robin.
#least_conn;
server dockernginxphpfpm_php1_1:9000;
server dockernginxphpfpm_php2_1:9000;
server dockernginxphpfpm_php3_1:9000;
}
Это не действительно идеально, потому что он потребует изменения конфигурации nginx и докера-compose.yml, когда Вы захотите увеличиться или вниз.
Примечание, что 9 000 портов являются внутренними к контейнеру и не Вашему фактическому хосту, таким образом, не имеет значения, что у Вас есть несколько php-fpm контейнеров на порте 9000.
Докер приобрел Tutum этой осенью. У них есть решение, которое комбинирует контейнер HAProxy с их API для автоматической корректировки конфигурации подсистемы балансировки нагрузки к рабочим контейнерам, это - выравнивание нагрузки. Это - хорошее решение. Затем nginx указывает на имя хоста, присвоенное подсистеме балансировки нагрузки. Возможно, Докер далее интегрирует этот тип решения в их инструменты после приобретения Tutum. Существует статья об этом здесь: https://web.archive.org/web/20160628133445/https://support.tutum.co/support/solutions/articles/5000050235-load-balancing-a-web-service
Tutum в настоящее время является заплаченным сервисом. Владелец ранчо является проектом с открытым исходным кодом, который обеспечивает подобную функцию выравнивания нагрузки. У них также есть "владелец-ранчо-compose.yml", который может определить выравнивание нагрузки и масштабирование сервисной установки в докере-compose.yml. http://rancher.com/the-magical-moment-when-container-load-balancing-meets-service-discovery/ http://docs.rancher.com/rancher/concepts/#load-balancer
ОБНОВЛЕНИЕ 06.03.2017: я использовал проект, названный взаимная блокировка , который работает с Докером, чтобы автоматически обновить конфигурацию nginx и перезапустить ее. Также посмотрите @iwaseatenbyagrue ответ , который имеет дополнительные подходы.
В случае, где Ваш Nginx и php-fpm контейнеры находятся на том же хосте, Вы можете настроить маленькое экземпляр dnsmasq на хосте, который будет использоваться контейнером Nginx и запускаете скрипт для автоматического обновления записи DNS, когда IP-адрес контейнера изменился.
я записал маленький сценарий , чтобы сделать это (вставляемый ниже), которые автоматически обновляют запись DNS, которая имеет то же имя как имя контейнеров и указывает на них на IP-адреса контейнеров:
#!/bin/bash
# 10 seconds interval time by default
INTERVAL=${INTERVAL:-10}
# dnsmasq config directory
DNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.}
# commands used in this script
DOCKER=${DOCKER:-docker}
SLEEP=${SLEEP:-sleep}
TAIL=${TAIL:-tail}
declare -A service_map
while true
do
changed=false
while read line
do
name=${line##* }
ip=$(${DOCKER} inspect --format '{{.NetworkSettings.IPAddress}}' $name)
if [ -z ${service_map[$name]} ] || [ ${service_map[$name]} != $ip ] # IP addr changed
then
service_map[$name]=$ip
# write to file
echo $name has a new IP Address $ip >&2
echo "host-record=$name,$ip" > "${DNSMASQ_CONFIG}/docker-$name"
changed=true
fi
done < <(${DOCKER} ps | ${TAIL} -n +2)
# a change of IP address occured, restart dnsmasq
if [ $changed = true ]
then
systemctl restart dnsmasq
fi
${SLEEP} $INTERVAL
done
Затем запустите свой nginx контейнер с --dns host-ip-address
, где host-ip-address
IP-адрес хоста в интерфейсе docker0
.
Ваш конфигурация Nginx должна разрешить имена динамично:
server {
resolver host-ip-address;
listen 80;
server_name @server_name@;
root /var/www/@root@;
index index.html index.htm index.php;
location ~ ^(.+?\.php)(/.*)?$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$1;
set $backend "@fastcgi_server@";
fastcgi_pass $backend;
}
}
Ссылки:
, Если Ваш nginx и php-fpm находятся на различных хостах, можно попробовать ответ @smaj.
Можно использовать восходящий поток для определения нескольких бэкендов, как описано здесь:
https://stackoverflow.com/questions/5467921/how-to-use-fastcgi-next-upstream-in-nginx
Вы также хотели бы обновить конфигурацию каждый раз, когда новые бэкенды умирают/входят сервис с чем-то как:
Другой подход мог бы быть должен изучить что-то как шаблон консула .
И конечно, в какой-то момент, Kubernetes, возможно, должен быть упомянут.
Однако Вы могли считать немного больше 'битами строки и клейкой ленты' подход путем взгляда на то, что потребление событий докера могло сделать для Вас (работайте docker events --since 0
за быстрым образцом).
Это было бы довольно тривиально, чтобы иметь сценарий, смотрящий на эти события (принимающий во внимание, что существует несколько клиентских доступных пакетов, включая для Python, пойдите, и т.д.), исправляя файл конфигурации, и перезагружая nginx (т.е. с помощью подхода шаблона консула, но без потребности в консуле).
Для возвращения к исходной предпосылке, хотя: пока Ваши php-fpm контейнеры запускаются со своей собственной сети (т.е. не совместное использование того из другого контейнера, такого как nginx один), затем у Вас может быть столько контейнеров, слушающих на порте 9000, сколько Вы хотите - поскольку у них есть дюйм/с на контейнер, нет никакой проблемы с портами 'столкновения'.
, Как Вы масштабируетесь, это будет, вероятно, зависеть от того, какова Ваша конечная цель/use-case, но одна вещь, которую Вы могли бы рассмотреть, помещает HAproxy между nginx и Вашими php-fpm узлами. Одна вещь, которую это могло позволить Вам делать, просто назначают диапазон (и возможно создайте docker network
) для Ваших php-fpm серверов (т.е. 172.18.0.0/24), и имеют HAproxy, настроенный, чтобы попытаться использовать любой IP в том диапазоне как бэкенд. Так как HAproxy имеет проверки состояния, он мог быстро определить, какие адреса живы, и используют их.
Видят https://stackoverflow.com/questions/1358198/nginx-removing-upstream-servers-from-pool для дискуссии о том, как nginx по сравнению с haproxy имеет дело с восходящими потоками.
, Если Вы не использовали специализированную сеть докера для этого, Вы могли бы потребность сделать некоторое ручное управление IP для Ваших php-fpm узлов.
Хотя это сообщение с 2015, и я чувствую, что я - некролуг (жаль сообщество), я чувствую, что ценно добавить в данный момент:
В наше время (и так как Kubernetes был упомянут), когда Вы работаете с Докером, можно использовать Kubernetes или Docker Swarm очень легко для решения этой проблемы. Оба дирижера возьмут в Ваших узлах докера (один узел = один сервер с Докером на нем), и можно развернуть сервисы для них, и они будут управлять проблемами порта для Вас использующий оверлейные сети.
, Поскольку я являюсь более сведущим в Рое Докера, это - то, как Вы сделали бы это для приближения к этой проблеме (предполагающий, что у Вас есть единственный узел Докера):
Инициализируют рой:
docker swarm init
CD в Ваш корень проекта
cd some/project/root
создает стопку роя от Вашего докера-compose.yml (вместо того, чтобы использовать докера - сочиняют):
docker stack deploy -c docker-compose.yml myApp
Это создаст сервисную стопку роя докера, названную "myApp", и будет управлять портами для Вас. Это означает: только необходимо добавить один "порт: 9000:9000" определение Вашему php-fpm сервису в Вашем докере - составляет файл, и затем можно увеличить масштаб php-fpm сервиса, сказать 3 экземплярам, в то время как рой будет автоволшебно баланс загрузки запросы между этими тремя экземплярами без дальнейшей необходимой работы.