我已经在Yii2
上部署了基于PHP
的{{1}}应用程序。基本上,OpenShift
在基于Yii2
且已安装alpine
和PHP
的容器中运行。容器公开Nginx
,然后将其绑定到port 8080
服务,在该服务中依次创建带有OpenShift
的安全路由。
大多数应用程序都可以正常工作,但是在进行Edge encryption
发布以及稍后在控制器中进行重定向时,HTTP
重定向到Yii2
而不是停留在http://<sitename>
,导致该应用程序无法正常工作。 https
请求本身可以工作,因为随后对数据库进行了更改,它的重定向返回到在这种情况下不起作用的概述。
控制器动作非常简单和标准:
POST
有关OpenShift配置的一些信息:
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['index']);
}
return $this->render('update', [
'model' => $model,
]);
}
用于创建应用程序的Dockerfile并不十分出色,它基本上安装了~ oc get routes
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
backend backend.apps.<instance> backend backend edge None
frontend frontend.apps.<instance> frontend frontend edge None
~ oc describe route backend
Name: backend
Namespace: <project>
Created: 10 hours ago
Annotations: openshift.io/host.generated=true
Requested Host: backend.apps.<instance>
exposed on router router 10 hours ago
Path: <none>
TLS Termination: edge
Insecure Policy: <none>
Endpoint Port: backend
Service: backend
Weight: 100 (100%)
Endpoints: <ip>:8080
,PHP
并设置了一些权限。 Nginx
配置实际上可能是问题的一部分,在下面发布了经过清理的版本。
Nginx
编辑1:
在Nginx配置中添加以下行使其可以工作,但是它不是一个很好的解决方案:
worker_processes 1;
error_log stderr warn;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main_timed '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time $pipe $upstream_cache_status';
access_log /dev/stdout main_timed;
error_log /dev/stderr notice;
keepalive_timeout 65;
server {
listen [::]:8080 default_server;
listen 8080 default_server;
server_name _;
sendfile off;
root /var/www/html/backend/web/;
index index.php index.html;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to index.php
try_files $uri $uri/ /index.php?q=$uri&$args;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/lib/nginx/html;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
expires 5d;
}
# deny access to . files, for security
#
location ~ /\. {
log_not_found off;
deny all;
}
# allow fpm ping and status from localhost
#
location ~ ^/(fpm-status|fpm-ping)$ {
access_log off;
allow 127.0.0.1;
deny all;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
}
}
}
但是,这假定始终使用HTTP。但是,这取决于OpenShift路由的配置。是否有更好的(更通用的)解决方案?
答案 0 :(得分:1)
OpenShift路由器(公开您创建的安全路由的路由器)将在请求上为运行Yii2应用程序的后端Pod设置多个headers。
我们要做的第一件事是在Nginx上信任这些标头,以便将它们转发到后端Yii2应用程序。
location ~ \.php$ {
proxy_pass_header X-Forwarded-Proto;
proxy_pass_header X-Forwarded-Host;
proxy_pass_header X-Forwarded-Port;
[...]
X-Forwarded-Proto
将设置为https
,并且看来Yii2将正确处理标头,但我之前从未使用过该PHP框架。如果需要的话,这将是第二步,这将使框架工艺响应URL带有x-forward-proto头中的协议。
此处应注意,如果不受信任的用户可以直接访问Nginx,则在Nginx级别信任这些标头可能很危险。在这种情况下,他们将能够欺骗请求并将这些标头设置为所需的任何内容。
答案 1 :(得分:1)
感谢所有评论和答案,我得以弄清楚。我不是在这里使用Nginx作为代理,而是在使用FastCGI for PHP,这就是为什么我不确定Jason提出的答案是否可行的原因。以下解决方案对我有用:
location ~ \.php$ {
set $my_https 'off';
if ($http_x_forwarded_proto = 'https') {
set $my_https 'on';
}
fastcgi_param HTTPS $my_https;
也许有一个更优雅的解决方案,但是这个对我有用