Before I start, I know there are many solutions in StackOverflow regarding this issue but they are not working for my case.
I set up a docker container running Nginx instance with PHP. When I enter such URL, myapp.com/somefile without .php at the end, it cannot find the file. I need to browse this URL to make it work myapp.com/somefile.php.
Here is my configuration with Dockerfile and Nginx config.
Dockerfile
FROM php:7.4.8-fpm
RUN apt-get update -y \
&& apt-get install -y nginx
# PHP_CPPFLAGS are used by the docker-php-ext-* scripts
ENV PHP_CPPFLAGS="$PHP_CPPFLAGS -std=c++11"
RUN docker-php-ext-install pdo_mysql \
&& docker-php-ext-install opcache \
&& apt-get install libicu-dev -y \
&& docker-php-ext-configure intl \
&& docker-php-ext-install intl \
&& apt-get remove libicu-dev icu-devtools -y
RUN { \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=4000'; \
echo 'opcache.revalidate_freq=2'; \
echo 'opcache.fast_shutdown=1'; \
echo 'opcache.enable_cli=1'; \
} > /usr/local/etc/php/conf.d/php-opcache-cfg.ini
COPY nginx-site.conf /etc/nginx/sites-enabled/default
COPY entrypoint.sh /etc/entrypoint.sh
COPY --chown=www-data:www-data . /var/www/html
WORKDIR /var/www/html
EXPOSE 80 443
ENTRYPOINT ["sh", "/etc/entrypoint.sh"]
nginx-site.conf
server {
root /var/www/html;
include /etc/nginx/default.d/*.conf;
index index.php index.html index.htm;
client_max_body_size 30m;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}
How can I solve this issue? Any help would be appreciated!
Note: I tried to add this lines of code to the nginx config but i ended up downloading files instead of executing them :
location / {
try_files $uri $uri.html $uri/ @extensionless-php;
index index.html index.htm index.php;
}
location ~ \.php$ {
try_files $uri =404;
}
location @extensionless-php {
rewrite ^(.*)$ $1.php last;
}
Yes, you cannot force nginx to force serving PHP script via PHP location
handler with something like try_files $uri $uri.php ...
. You can try this config instead (yes, I know that some if
blocks are evil, but don't worry, this one isn't):
location / {
index index.html index.htm index.php;
try_files $uri $uri.html $uri/ @extensionless-php;
}
location ~ \.php$ {
# default PHP handler here, e.g.
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location @extensionless-php {
if ( -f $document_root$uri.php ) {
rewrite ^ $uri.php last;
}
return 404;
}
If you want to redirect all the not found requests to index.php
, use this one instead:
location @extensionless-php {
if ( -f $document_root$uri.php ) {
rewrite ^ $uri.php last;
}
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
To make URIs with trailing slashes workable too - e.g., both /somefile
and /somefile/
- the named location should be changed as follows:
location @extensionless-php {
rewrite ^(/.*)/$ $1;
if ( -f $document_root$uri.php ) {
rewrite ^ $uri.php last;
}
return 404;
}
for the first configuration example, and as follows:
location @extensionless-php {
rewrite ^(/.*)/$ $1;
if ( -f $document_root$uri.php ) {
rewrite ^ $uri.php last;
}
break;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
}
for the second one.
Note: Only URIs that do not correspond to physical directories under the web server root will be processed with the above configurations.