I need to run a TYPO3 website on Nginx in a subdirectory of a domain: example.com/subdir.
The website is running well for normal pages, but not for pages with tx_news-records. As soon as I call a news detail page (example.com/subdir/detailpages/slug-of-news-record.html), I get the following error:
#1537633463 OutOfRangeException
Hash not resolvable
This is my Nginx config:
location ^~/subdir {
alias /var/www/html/subdirectory;
disable_symlinks off;
index index.php index.html index.htm;
try_files $uri $uri/ #subdir;
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~* ^/subdir/fileadmin/(.*/)?_recycler_/ {
deny all;
}
location ~* ^/subdir/typo3conf/ext/[^/]+/Resources/Private/ {
deny all;
}
location ~* ^/subdir/(fileadmin/|typo3conf/|typo3temp/|uploads/|favicon\.ico) {
}
}
location #subdir {
rewrite /subdir/(.*)$ /subdir/index.php?/$1$is_args$args last;
}
location ~* ^/subdir/(.*$) {
return 301 /subdir/$1;
}
What is missing in my Nginx config and is there something in general which I need to approve?
After some trial and error I found the solution myself. The following configuration is working for me:
location ^~/subdir {
alias /var/www/html/subdirectory;
disable_symlinks off;
index index.php index.html index.htm;
try_files $uri $uri/ #subdir;
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~* ^/subdir/fileadmin/(.*/)?_recycler_/ {
deny all;
}
location ~* ^/subdir/typo3conf/ext/[^/]+/Resources/Private/ {
deny all;
}
location ~* ^/subdir/(fileadmin/|typo3conf/|typo3temp/|uploads/|favicon\.ico) {
}
}
location #subdir {
rewrite /subdir/(.*)$ /subdir/index.php?$args last;
}
location ~* ^/subdir/(.*$) {
return 301 /subdir/$1;
}
As always, it was just a tiny little change.
location #subdir {
rewrite /subdir/(.*)$ /subdir/index.php?/$1$is_args$args last;
}
Changed to
location #subdir {
rewrite /subdir/(.*)$ /subdir/index.php?$args last;
}
Related
I have been trying to setup a directory to use a seperate root directory (or alias).
location ~ \.php$ # root location
{
try_files $uri #php;
include /etc/openresty/fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
location ^~ /sub2/
{
rewrite_log on;
alias /var/www/sub2/;
location ~ \.php$
{
try_files $uri #ono_php;
include /etc/openresty/fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
}
try_files $uri #ono_main_cache;
}
location #ono_php
{
rewrite ^/sub2/(.+)$ /index.php?request=$1 last;
}
location #ono_main_cache
{
if ( $http_accept_encoding !~ gzip )
{
rewrite ^/sub2/(.*)$ /index.php?request=$1 last;
}
if ( $query_string )
{
rewrite ^/sub2/(.*)$ /index.php?request=$1 last;
}
try_files /var/www/sub2/data/cache/html$uri.html.gz #ono_php;
add_header Content-Encoding gzip;
gzip off;
default_type text/html;
}
There is more in the overall nginx configuration for the domain, but I've only included what is relevant.
To overview, I want the /sub2/ to use the root/alias /var/www/sub2/, rather than the default /var/www/site/. That works correctly. However, all URLs that don't load a file should be redirected to index.php as in the #ono_php block. However, they use the first location block listed (with # root location appended to it). So if I load the URL:
https://example.com/sub2/contact
It loads the same URL as:
https://example.com/contact
How can I get the block #ono_php to use the location ~ \.php$ defined inside location ^~ /sub2/?
There were a number of issues. The main being I set the root/alias to /var/www/sub2 and when requests were made, they had that directory appended from the URL, e.g. the path requested was /var/www/sub2/sub2/url - where sub2/url is the URL. Changing the root to /var/www fixed this.
location ^~ /sub2
{
root /var/www;
try_files $uri $uri/ #ono_main_cache;
location ~ \.php$
{
include /etc/openresty/fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
}
}
location #ono_php
{
rewrite ^/sub2/(.*)$ /sub2/index.php?request=$1 last;
}
location #ono_main_cache
{
if ( $http_accept_encoding !~ gzip )
{
rewrite ^/sub2/(.*)$ /sub2/index.php?request=$1 last;
}
if ( $query_string )
{
rewrite ^/sub2/(.*)$ /sub2/index.php?request=$1 last;
}
try_files /sub2/data/cache/html$uri.html.gz #ono_php;
add_header Content-Encoding gzip;
gzip off;
default_type text/html;
}
I am using nginx and my webservers htdocs folder contains several *.html files. I want to serve them even if the request doesn't contain the *.html extension.
Most answers I found here on SO apply a rewrite which will be visible in the browsers address bar. How can I achieve the same but "silently"?
Example:
www.example.com/foo => www.example.com/foo.html
If I'm not mistaken, then /opt/bitnami/apps/wordpress/conf/nginx-app.conf is the best location to apply these changes.
index index.php index.html index.htm;
if ($request_uri !~ "^/phpmyadmin.*$")
{
set $test A;
}
if ($request_uri !~ "^/bitnami.*$")
{
set $test "${test}B";
}
if (!-e $request_filename)
{
set $test "${test}C";
}
if ($test = ABC) {
rewrite ^/(.+)$ /index.php?q=$1 last;
}
# Deny access to any files with a .php extension in the uploads directory
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
# Disable logging for not found files and access log for the favicon and robots
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
include "/opt/bitnami/apps/bitnami/banner/conf/banner-substitutions.conf";
include "/opt/bitnami/apps/bitnami/banner/conf/banner.conf";
# Deny all attempts to access hidden files such as .htaccess or .htpasswd.
location ~ /\. {
deny all;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_read_timeout 300;
fastcgi_pass unix:/opt/bitnami/php/var/run/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}
You could use the try_files
location / {
try_files $uri $uri/ $uri.html =404;
}
document at https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files
index index.php index.html index.htm;
if ($request_uri !~ "^/phpmyadmin.*$")
{
set $test A;
}
if ($request_uri !~ "^/bitnami.*$")
{
set $test "${test}B";
}
if (!-e $request_filename)
{
set $test "${test}C";
}
if (!-e $request_filename.html)
{
set $test "${test}D";
}
if ($test = ABCD) {
rewrite ^/(.+)$ /index.php?q=$1 last;
}
location / {
try_files $uri $uri/ $uri.html =404;
}
# Deny access to any files with a .php extension in the uploads directory
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
# Disable logging for not found files and access log for the favicon and robots
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
include "/opt/bitnami/apps/bitnami/banner/conf/banner-substitutions.conf";
include "/opt/bitnami/apps/bitnami/banner/conf/banner.conf";
# Deny all attempts to access hidden files such as .htaccess or .htpasswd.
location ~ /\. {
deny all;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_read_timeout 300;
fastcgi_pass unix:/opt/bitnami/php/var/run/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
}
I have installed a Magento extension to have a wordpress blog integrated with Magento.
Basically, the WP is in a subdirectory of the Magento root. I want to create multiple sites with subdirectories but I can't make it work due to the nginx configuration.
Wordpress is in his /wp subdirectory (http://example.com/wp/wp-admin/) and the others sites are accessible from http://example.com/wp/ca/wp-admin/ and http://example.com/wp/en/wp-admin/
Here is whats I got so far :
server
{
server_name dev.example.com;
access_log /var/log/nginx/example.access.log;-
error_log /var/log/nginx/example.error.log;
root /var/www/example;
location ^~ /wp {
index index.php index.html index.htm;
try_files $uri $uri/ /wp/index.php?q=$uri&$args;
# Multisite
if (!-e $request_filename) {
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
rewrite ^/wp(/[^/]+)?(/wp-.*) /wp$2 last;
rewrite ^/wp(/[^/]+)?(/.*\.php)$ /wp$2 last;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass 127.0.0.1:9000;
}
}
set $mage_developer true;
set $mage_code es;
set $mage_type store;
include snippets.d/magento-site;-
}
and in snippets.d/magento-site :
# Serve static pages directly,
# otherwise pass the URI to Magento's front handler
location / {
index index.php;
try_files $uri $uri/ #handler;
expires 30d;-
}
# Disable .htaccess and other hidden files
location /. {
return 404;
}
# Allow admins only to view export folder
location /var/export/ {
auth_basic "Restricted";
auth_basic_user_file htpasswd;
autoindex on;
}
# These locations would be hidden by .htaccess normally
location /app/ { deny all; }
location /includes/ { deny all; }
location /lib/ { deny all; }
location /media/downloadable/ { deny all; }
location /pkginfo/ { deny all; }
location /report/config.xml { deny all; }
location /var/ { deny all; }
# Magento uses a common front handler
location #handler {
rewrite / /index.php;
}
# Forward paths like /js/index.php/x.js to relevant handler
location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}
# Execute PHP scripts
location ~ .php$ {
# Catch 404s that try_files miss
if (!-e $request_filename) { rewrite / /index.php last; }
expires off;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param MAGE_RUN_CODE $mage_code;
fastcgi_param MAGE_RUN_TYPE $mage_type;
fastcgi_ignore_client_abort on;
fastcgi_read_timeout 900s; # 15 minutes
}
Thanks for your help.
Wanted to pass along a full conf file for anyone who needs to configure this. Please keep in mind, many file paths are unique your your server configuration.
Please note, you'll need to adjust the following parameters based on file paths on your server:
server_name domain.com www.domain.com;
ssl_certificate /sslpath/domain.com.crt;
ssl_certificate_key /sslpath/domain.com.key;
root /webrootpath/domain.com;
rewrite ^/blogpath(.*) /blogpath/index.php?q=$1;
location ^~ /blogpath {
error_log /data/log/nginx/domain.com_error.log;
access_log /data/log/nginx/domain.com_access.log;
Here is the full nginx conf file:
server {
listen 80;
server_name domain.com www.domain.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name domain.com www.domain.com;
ssl on;
ssl_certificate /sslpath/domain.com.crt;
ssl_certificate_key /sslpath/domain.com.key;
ssl_session_timeout 30m;
root /webrootpath/domain.com;
index index.php;
location / {
index index.html index.php;
try_files $uri $uri/ #handler;
expires 30d;
}
location #wp {
rewrite ^/blogpath(.*) /blogpath/index.php?q=$1;
}
location ^~ /blogpath {
root /webrootpath/domain.com;
index index.php index.html index.htm;
try_files $uri $uri/ #wp;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass 127.0.0.1:9000;
}
}
location ~ ^/(app|includes|lib|media/downloadable|pkginfo|report/config.xml|var)/ { internal; }
location /var/export/ { internal; }
location /. { return 404; }
location #handler { rewrite / /index.php; }
location ~* .php/ { rewrite ^(.*.php)/ $1 last; }
location ~* .php$ {
if (!-e $request_filename) { rewrite / /index.php last; }
expires off;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param MAGE_RUN_CODE default;
fastcgi_param MAGE_RUN_TYPE store;
include fastcgi_params;
}
error_log /data/log/nginx/domain.com_error.log;
access_log /data/log/nginx/domain.com_access.log;
}
Well, in the end, it works passing all request to the blog to Apache and creating the site in the virtual hosts corresponding.
location ~ ^/blog {
proxy_pass http://apache:80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 6000s;
}
If someone succeed to make it work with Nginx only, I'm looking forward to his answer :)
Why run Apache? Doesn't make sense to run 2 webservers.
Try adding this to your nginx conf.
location #wp {
rewrite ^/wp(.*) /wp/index.php?q=$1;
}
location ^~ /wp {
root /var/www/example;
index index.php index.html index.htm;
try_files $uri $uri/ #wp;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass 127.0.0.1:9000;
}
}
This is a snippet of my nginx configuration for Drupal:
server {
listen 80;
server_name _;
root /home/testing/public_html/staging;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /backup {
deny all;
}
location ~* \.(txt|log)$ {
deny all;
}
location / {
try_files $uri #rewrite;
}
location #rewrite {
rewrite ^/(.*)$ /index.php?q=$1;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
fastcgi_pass unix:/tmp/php-fpm.sock;
}
location ~ ^/sites/.*/files/imagecache/ {
try_files $uri #rewrite;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
rewrite ^/staging/(.*)$ /$1;
expires max;
log_not_found off;
}
}
This works perfectly fine with URLs like these
http://www.testing.com/this/page
http://www.testing.com/that/page
until a hard-coded URL containing "/staging/" is processed. Example:
http://www.testing.com/staging/this/page
This displays the "Page not found" page. I tried adding this line:
location /staging {
rewrite ^/staging/(.*)$ /index.php?q=$1;
}
but this doesn't appear to work at all. How do I catch all URLs with "/staging/" and rewrite them properly so I don't get the "Page not found" error?
You need to add last to trigger another round of location match. Without it, your request is trapped in the /staging location block.
location /staging {
rewrite ^/staging/(.*)$ /index.php?q=$1 last;
}
Check your website configuration by trying this one.
Here is an example of working Nginx configuration
If it doesn't work, post your error logs.
server {
listen 80;
server_name www.site.dk;
access_log /var/www/www.site.dk/logs/access.log;
error_log /var/www/www.site.dk/logs/error.log;
root /var/www/www.site.dk/;
location / {
index index.php index.html;
if (-f $request_filename) {
break;
}
if (!-f $request_filename) {
rewrite ^/(.+)$ /index.php last;
break;
}
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/www.site.dk$fastcgi_script_name;
}
}
I'm trying to get nginx to serve any physical file (css, images, js) without doing anything to it put let php handle all other requests. Everything that is not a physical file should be passed to php.
But it's not working, php is being executed, but calling a .css file is also passed to php as a request.
This will do the job
server {
listen 80;
server_name www.site.dk;
access_log /var/www/www.site.dk/logs/access.log;
error_log /var/www/www.site.dk/logs/error.log;
root /var/www/www.site.dk/;
index index.php index.html;
location / {
try_files $uri $uri/ #fastcgi;
}
location ~ .+\.php$ {
location ~ \..*/.*\.php$ { return 400; }
error_page 418 = #fastcgi;
return 418;
}
location #fastcgi {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
...
}
}