В настоящее время я пытаюсь развернуть приложение Symfony в настройке Docker. Текущая настройка:
[ Traefik ] -> [ Nginx ] -> [ PHP-FPM ]
- Traefik - точка доступа, обрабатывающая сертификаты SSL (с использованием опции
dnsChallenge
). - Nginx обрабатывает обслуживаниестатических файлов (активов и тому подобного), имеет
traefik.frontend.rule
как label
для назначения домена - PHP-FPM выполняет код PHP
Генерация сертификатаTraefik
работает без проблем, напр. Traefik Dashboard и Portainer работают без проблем. Однако когда я получаю доступ к приложению Symfony через браузер, Symfony думает, что оно не подключено по HTTPS. Поле url в браузере содержит https://foo.example.tld
, но контент, контролируемый Symfony, возвращается к http
, напр. изображения или URL-адреса, которые генерируются с использованием абсолютного пути.
var_dump($request->getScheme(), $request->getSchemeAndHttpHost()); // 'http' and 'http://example.tld'
Я полагаю, что это имеет смысл, поскольку соединение между Traefik
и Nginx
использует порт80. Если я назначу порт 443 для Nginx
и получу Nginx
прослушивание этого порта вместо порта 80, я получу тот же результат.
Итак, вопрос в том, как это исправить? Нужно ли генерировать локальный сертификат SSL, и нужно ли Nginx
загрузить его и указать Traefik
, чтобы использовать его? Есть ли другой способ? Нужно ли пересылать что-либо еще на Traefik
или Nginx
// docker-compose.yml (shortened)
version: '3.7'
services:
traefik:
image: traefik:1.7
container_name: traefik
command: --api --docker --docker.exposedbydefault=false
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/traefik.prod.toml:/traefik.toml
- acme-storage:/acme:rw
labels:
- traefik.enable=true
- traefik.backend=medison-traefik
- traefik.frontend.rule=Host:dashboard.example.tld
- traefik.port=8080
restart: always
webserver:
image: nginx:alpine
container_name: webserver
volumes:
- ./storage/uploads:/var/www/html/web/uploads:ro
- ./config/nginx.prod.conf:/etc/nginx/conf.d/default.conf:ro
working_dir: /var/www/html/web
depends_on:
- php-fpm
labels:
- traefik.enable=true
- traefik.backend=webserver
- traefik.frontend.rule=Host:foo.example.tld
restart: always
php-fpm:
image: user/image:master
container_name: php-fpm
volumes:
- ./storage/uploads:/var/www/html/web/uploads:rw
- ./logs/php:/var/www/var/logs:rw
working_dir: /var/www/html/web
restart: always
volumes:
acme-storage:
// nginx.prod.conf
server {
listen 80 default;
client_max_body_size 108M;
access_log /var/log/nginx/application.access.log;
root /var/www/html/web;
index app.php;
if (!-e $request_filename) {
rewrite ^.*$ /app.php last;
}
location ~ \.php$ {
fastcgi_pass php-fpm:9000;
fastcgi_index app.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log";
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
include fastcgi_params;
}
}
Для теста с портом 443 я изменил в nginx.prod.conf
line 2 listen 80 default;
на listen 443 default;
и добавил - traefik.port=443
к docker-compose.yml
после - traefik.frontend.rule=Host:foo.example.tld