Hi!
I have some basic experience with nginx but now I need help to debug this configuration.
The logic is ported from Apache’s .htaccess file and it was working for years and for sure I did something wrong while porting it to nginx. Everything works as expected except the part with watermark which is just ignored.
The idea is to intercept requests to /photos/*.jpg and let the PHP file generate the result while URL does not change to client that made a request.
The location of photo files on actual machine is /var/www/vintagezagreb.net/photos/.
Example:
Request: https://vintagezagreb.net/photos/fe6a89c3-6069-6497-4f94-b42d70803f1f.jpg
The result: https://vintagezagreb.net/watermarked.php?file=fe6a89c3-6069-6497-4f94-b42d70803f1f.jpg
Thanks!
# go away from "http"
server {
if ($host = www.vintagezagreb.net) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = vintagezagreb.net) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name vintagezagreb.net www.vintagezagreb.net;
server_tokens off;
client_max_body_size 20M;
return 301 https://vintagezagreb.net$request_uri;
}
# remove "www"
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.vintagezagreb.net;
server_tokens off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
client_max_body_size 20M;
return 301 https://vintagezagreb.net$request_uri;
# ssl_certificate ...
# ssl_certificate_key ...
}
# main configuration for SmijSe
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name vintagezagreb.net;
root /var/www/vintagezagreb.net; # matches your extracted files
index index.php;
server_tokens off;
client_max_body_size 20M;
# Security headers
add_header Referrer-Policy origin always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Logging
access_log /var/log/nginx/php-access.log;
error_log /var/log/nginx/php-error.log;
# Gzip
gzip on;
gzip_min_length 512;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain application/xml text/css application/javascript application/json;
# PHP-FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_param HTTP_PROXY "";
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
# Protect .ht* files
location ~ /\.ht {
deny all;
return 403;
}
# Static files caching
location ~ \.(gif|ico|jpg|png|svg|js|css|htm|html|mp3|mp4|wav|ogg|avi|ttf|eot|woff|woff2)$ {
allow all;
expires 1h;
add_header Pragma public;
add_header Cache-Control "public";
}
# watermark
location ~ ^/photos/(.*)\.jpg$ {
try_files /watermarked.php?file=$1 =404;
# tried also with `.jpg` suffix which way my 1st choice
# try_files /watermarked.php?file=$1.jpg =404;
}
# allow short URL without `/photos/`
rewrite "^/([0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12})$" /photos/$1 permanent;
# photo page
location ~ "^/photos/([0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12})$" {
rewrite ^/photos/([0-9a-f\-]+)$ /photo.php?id=$1 last;
}
# story page
location ~ "^/stories/([0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12})$" {
rewrite ^/stories/([0-9a-f\-]+)$ /story.php?id=$1 last;
}
# tag page
location ~ ^/tags/(.+)$ {
rewrite ^/tags/(.+)$ /tag.php?tag=$1 last;
}
# favicon
location = /favicon.ico {
rewrite ^ /favicon/favicon.ico last;
}
location = /safari-pinned-tab.svg {
rewrite ^ /favicon/safari-pinned-tab.svg last;
}
location = /browserconfig.xml {
rewrite ^ /favicon/browserconfig.xml last;
}
location = /manifest.json {
rewrite ^ /favicon/manifest.json last;
}
rewrite ^/apple-touch-(.*)\.png$ /favicon/apple-touch-$1.png last;
rewrite ^/android-chrome-(.*)\.png$ /favicon/android-chrome-$1.png last;
rewrite ^/mstile-(.*)\.png$ /favicon/mstile-$1.png last;
rewrite ^/favicon-(.*)\.png$ /favicon/favicon-$1.png last;
# ssl_certificate ...
# ssl_certificate_key ...
}