3

我目前尝试在 Docker 设置中部署 Symfony 应用程序。当前设置是:

[ Traefik ] -> [ Nginx ] -> [ PHP-FPM ]

  • Traefik 是入口点,处理 SSL 证书(使用dnsChallenge选项)。
  • Nginx 处理静态文件(资产和那些东西)的服务,有一个traefik.frontend.ruleaslabel来分配域
  • 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 分配给NginxNginx在该端口上侦听而不是端口 80,我会得到相同的结果。

所以问题是,我该如何解决这个问题?我是否必须生成本地 SSL 证书,并Nginx加载并告诉Traefik使用它?还有其他方法吗?我是否需要转发其他任何内容TraefikNginx

// 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第 2 行更改listen 80 default;listen 443 default;并添加- traefik.port=443docker-compose.yml之后- traefik.frontend.rule=Host:foo.example.tld

4

1 回答 1

3

当我使用 Ingress 将项目移动到 kubernetes 时,我在从 htts 重定向到 http 时遇到了同样的问题。我设置了受信任的代理来请求。它有帮助。
https://symfony.com/doc/4.4/deployment/proxies.html

// public/index.php

// ...
Request::setTrustedProxies(
    // trust *all* requests (the 'REMOTE_ADDR' string is replaced at
    // run time by $_SERVER['REMOTE_ADDR'])
    ['127.0.0.1', 'REMOTE_ADDR'],

    // if you're using ELB, otherwise use a constant from above
    Request::HEADER_X_FORWARDED_AWS_ELB
);
于 2020-03-05T09:08:43.040 回答