I have a huge difficulty to achieve what I want to do on Nginx.
For a client, I have a blog using WordPress and a marketplace using Symfony 5.4. PHP version is 7.4 FPM.
The blog is under folder /var/www/blog/ with user and group www-data:www-data and should be accessible from https://my-domain.com
The marketplace is under folder /var/www/marketplace/ with user and group www-data:www-data and should be accessible from https://my-domain.com/marketplace/
I try a tone of different configurations found on the internet or using ChatGPT (just in case) without success.
Each time I've got a blog working or not and the marketplace is not found or I've got the error "file not found".
Could someone help me to have a basic idea of how to implement it? The basic configuration will be enough.
I will really appreciate your help :)
EDIT:
Here is my last try. Wordpress is working but when I try to access to https://my-website/symfony/ I've got a 404 not found of Wordpress.
client_max_body_size 0;
# DDoS Mitigation
##Limit the number of connections per IP
limit_conn_zone $binary_remote_addr zone=engine_con:10m;
limit_conn_status 429;
##Limit the number of requests per session
limit_req_zone $binary_remote_addr zone=engine_req:10m rate=50r/s;
limit_req_zone $binary_remote_addr zone=static_req:10m rate=100r/s;
limit_req_status 429;
# End DDoS Mitigation
server {
listen 80;
listen [::]:80;
server_name my-website.fr www.my-website.fr;
#add_header X-Frame-Options DENY;
#add_header Strict-Transport-Security 'max-age=15768000; includeSubDomains; preload';
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "0";
#add_header Referrer-Policy no-referrer-when-downgrade;
add_header Referrer-Policy origin-when-cross-origin;
add_header Feature-Policy "midi 'none';";
#add_header Content-Security-Policy "default-src * blob: 'unsafe-inline' 'unsafe-eval'; img-src * 'self' blob: data: https://*.googleapis.com https://*.gstatic.com;";
#return 301 https://www.my-website.fr$request_uri;
return 301 https://my-website.fr$request_uri;
}
server {
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/my-website.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-website.fr/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name www.my-website.fr;
#add_header X-Frame-Options DENY;
#add_header Strict-Transport-Security 'max-age=15768000; includeSubDomains; preload';
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "0";
#add_header Referrer-Policy no-referrer-when-downgrade;
add_header Referrer-Policy origin-when-cross-origin;
add_header Feature-Policy "midi 'none';";
#add_header Content-Security-Policy "default-src * blob: 'unsafe-inline' 'unsafe-eval'; img-src * 'self' blob: data: https://*.googleapis.com https://*.gstatic.com;";
#return 301 https://www.my-website.fr$request_uri;
return 301 https://my-website.fr$request_uri;
}
server {
listen [::]:443 ssl ipv6only=on http2;
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/my-website.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-website.fr/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name my-website.fr;
root /var/www/wordpress;
index index.php;
#add_header X-Frame-Options DENY;
add_header Strict-Transport-Security 'max-age=15768000; includeSubDomains; preload';
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "0";
#add_header Referrer-Policy no-referrer-when-downgrade;
add_header Referrer-Policy origin-when-cross-origin;
add_header Feature-Policy "midi 'none';";
#add_header Content-Security-Policy "default-src * blob: 'unsafe-inline' 'unsafe-eval'; img-src * 'self' blob: data: https://*.googleapis.com https://*.gstatic.com;";
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types application/font-woff application/javascript application/rss+xml application/vnd.ms-fontobject application/x-font application/x-font-opentype application/x-font-otf application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/opentype font/otf font/ttf image/svg+xml image/x-icon text/css text/javascript text/plain text/xml;
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/htpasswd;
# DDoS Mitigation
limit_conn engine_con 100;
# End DDoS
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = (/|/symfony) {
return 301 https://my-website.fr/symfony/fr/;
}
location ~ ^/symfony/ {
root /var/www/symfony/current/public;
index index.php;
# DDoS Mitigation
limit_conn engine_con 100;
location ^/symfony/api/ {
limit_req zone=engine_req burst=5 nodelay;
try_files $uri /index.php$is_args$args;
}
location ~ ^/symfony/(assets|bundles|images|json)/ {
limit_req zone=static_req burst=10 nodelay;
}
location ~ ^/symfony/media/cache/(?!resolve)/ {
limit_req zone=static_req burst=10 nodelay;
}
# End DDoS Mitigation
location ~ ^/symfony/ {
try_files $uri /index.php$is_args$args;
# SecRulesEnabled;
# LearningMode;
# CheckRule "$SQL >= 8" BLOCK;
# CheckRule "$RFI >= 8" BLOCK;
# CheckRule "$TRAVERSAL >= 4" BLOCK;
# CheckRule "$EVADE >= 4" BLOCK;
# CheckRule "$XSS >= 8" BLOCK;
# DeniedUrl "/403.html";
}
location ~ ^/symfony/403.html {
return 403;
}
location ~ elfinder\.main\.js$ {
try_files $uri /index.php$is_args$args;
}
location ~ ^/symfony/media/cache/resolve/ {
try_files $uri /index.php$is_args$args;
}
#location ~* \.(ico|css|js|woff|ttf|png|jpg|gif|jpeg|svg)$ {
# expires 1m;
#}
location ~ ^/symfony/index.php(/|$) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_buffers 16 32k;
fastcgi_buffer_size 32k;
fastcgi_busy_buffers_size 32k;
internal;
}
location ~ ^/symfony/uploads {
if ($request_filename !~* .(gif|jpe?g|jpe|jfif|gif|png|ico|tiff?|pdf|xml|docx?|xlsx?|pptx?|csv)$) {
return 404;
}
}
location ~ ^/symfony/admin {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/htpasswd-exports;
autoindex on;
}
location ~ ^/symfony/server/log/(.*)$ {
add_header Content-Type text/html;
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/htpasswd-tools;
alias /var/www/symfony/shared/var/log/$1;
autoindex on;
}
location ~ /\. {
return 404;
}
location ~ \.php$ {
return 404;
}
}
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_pass 127.0.0.1:9000;
#The following parameter can be also included in fastcgi_params file
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
I found a solution using this server configuration below:
server {
listen [::]:443 ssl ipv6only=on http2;
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/my-website.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-website.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name my-website.com;
root /var/www/wordpress;
index index.php app.php index.html;
location /symfony {
root $symfonyRoot;
rewrite ^/symfony/(.*)$ /$1 break;
try_files $uri @symfonyFront;
}
location ~ ^/assets/(.*)$ {
rewrite ^/assets/(.*)$ /symfony/assets/$1 permanent;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
set $symfonyRoot /var/www/symfony/public;
set $symfonyScript index.php;
# This is for the Symfony application
location @symfonyFront {
fastcgi_pass 127.0.0.1:9000;
# include /etc/nginx/fastcgi_params;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $symfonyRoot/$symfonyScript;
fastcgi_param SCRIPT_NAME /symfony/$symfonyScript;
fastcgi_param REQUEST_URI /symfony$uri?$args;
}
# This is for the wordpress app
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REQUEST_URI $uri?$args;
# include /etc/nginx/fastcgi_params;
include fastcgi_params;
}
}