Appologies in advance, this is rather a long description, skip to the Problem peice below for my actual problem, also see the config files
I'm setting up an set of internal web sites for where I work, I decided to use nginx as the main app I use (GitLab) uses it underneath. Although I now think that maybe that wasn't so sensible !).
I can get GitLab to function just fine. I have temporarily 'turned it off' so as I can get the entry point to the pages up an running.
Background
The plan.
To run a single page for entry, and then have the various 'apps' running on sub domains.
So out main server is called reslab and then we will have the gitlab.reslab running on a subdomain, and then any other items we need on other subdomains.
So we we plan to put all our documentation into a mediawiki, so that will live on wiki.reslab
Also we expect to run a test version of the units web site, which will reside on testweb.reslab. Eventually I expect more things to end up on here, such as sub sites for specific projects.
As the main site is running on WordPress, I decided that I would use wordpress as the principle development option for the all the pages that may be created.
The problem
Whenever I open a link that is a php file, the file will be downloaded, rather than being executed.
At first I realised that the files in the document root weren't executable, but that didn't help.
I've checked the php config for the location of the socket file, which is as it appears in the config files below.
I had originally wanted to split the config file into smaller peices, but I got persistent errors when testing the config with nginx -t.
Have I included my files in the wrong place ? should they all be in the nginx.conf file (and not sitting in the relab.conf file?) ~ although placing them into the nginx.conf file just gave errors about items being double declared, and as they where for the worpress site it made sense in my mind to leave them within the site specific config file.
Is there a way to output the details of the files that are being included, so as I can be sure that I have missed a config file.
The system is running debian : Linux reslab 5.10.0-8-amd64 #1 SMP Debian 5.10.46-5 (2021-09-23) x86_64 GNU/Linux
I have installed php and nginx, and both are running
php :
sudo service php7.4-fpm status
● php7.4-fpm.service - The PHP 7.4 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php7.4-fpm.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2021-10-04 13:34:06 CEST; 7s ago
Docs: man:php-fpm7.4(8)
Process: 434953 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/7.4/fpm/pool.d/www.conf 74 (code=exited, status=0/SUCCESS)
Main PID: 434950 (php-fpm7.4)
Status: "Ready to handle connections"
Tasks: 3 (limit: 43238)
Memory: 9.8M
CPU: 56ms
CGroup: /system.slice/php7.4-fpm.service
├─434950 php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)
├─434951 php-fpm: pool www
└─434952 php-fpm: pool www
nginx :
sudo service nginx status
[sudo] password for davem:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2021-10-04 12:08:34 CEST; 1h 51min ago
Docs: man:nginx(8)
Process: 425978 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Process: 425979 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Main PID: 425980 (nginx)
Tasks: 13 (limit: 43238)
Memory: 11.7M
CPU: 73ms
CGroup: /system.slice/nginx.service
├─425980 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
├─425981 nginx: worker process
├─425982 nginx: worker process
├─425983 nginx: worker process
├─425984 nginx: worker process
├─425985 nginx: worker process
├─425986 nginx: worker process
├─425987 nginx: worker process
├─425988 nginx: worker process
├─425989 nginx: worker process
├─425990 nginx: worker process
├─425991 nginx: worker process
└─425992 nginx: worker process
Setup
I intend for the main site to be named as for the server, this is its nginx config.
/etc/nginx/nginx.conf
sudo more nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
#######################################################
### Config for Wordpress multi sites ########
#######################################################
worker_cpu_affinity auto; #worpress
##
# For Virtual Host Configs
##
# include /etc/nginx/conf.d/*.conf;
# include /etc/nginx/sites-enabled/*.conf; # I do this later on ...
events {
worker_connections 1024;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
# it may be internal, but I want to set up good practice
# internal pages using a self signed certificate
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
#error log levels are : warn, error crit, alert, and emerg
# just add one to the end of the below line before the ';'
# eg error_log /var/log/nginx/error.log warn;
error_log /var/log/nginx/error.log debug;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
#for the inclusion of other sites config files
include /etc/nginx/sites-enabled/*.conf;
# for wordpress to use php
# Upstream to abstract backend connection(s) for PHP.
upstream php {
#this should match value of "listen" directive in php-fpm pool
server unix:/var/run/php/php7.4-fpm.sock;
server 127.0.0.1:9000;
}
# below is for gitlab config that cannot be in the main server section.
upstream gitlab-workhorse {
server unix://var/opt/gitlab/gitlab-workhorse/sockets/socket fail_timeout=0;
}
}
sites-enabled
/etc/nginx/sites-enabled/reslab.conf :
# This will be our default landing page configuration
# All the sub sites, and this one, are using wordpress
# the exception is the gitlab subdomain
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
## Strong SSL Security
## see https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/
# ssl on; # this line is deprecated and replaced by the listen 0.0.0.0:443 directive above (just after the start of the server section)
ssl_certificate /etc/nginx/ssl/reslab.crt;
ssl_certificate_key /etc/nginx/ssl/reslab.key;
#Some extra ssl wordpress stuff
# Set caches, protocols, and accepted ciphers. This config will merit an A+ SSL Labs score as of Sept 2015.
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5';
# Enable HSTS. This forces SSL on clients that respect it, most modern browsers. The includeSubDomains flag is optional.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
#document root for the main langing page
root /var/www/reslab/wordpress;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php;
#ensure that all the sub server are considered equally using the '.reslab'
server_name 10.69.60.18 reslab .reslab *.reslab;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
#add specific logging for this server.
access_log /var/log/nginx/reslab_access.log;
#set to debug whilst troubleshooting php problems
error_log /var/log/nginx/reslab_error.log debug;
}
#set the mapping of this site to its relevant blog pages
# this needs to be outside of the server block (but in the http block)
map $http_host $blogid {
default -999;
#Ref: https://wordpress.org/extend/plugins/nginx-helper/
#include /var/www/wordpress/wp-content/plugins/nginx-helper/map.conf ;
}
#here is the wordpress specific stuff, that should be copied into most subdomains.
#remember to modify as required the server root if you have just made a simple copy of this file
server {
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
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?rt=$uri&$args;
}
# load the nginx php / fastCGI support module
include /etc/nginx/fcgiwrap.conf;
# this is required to tell nginx to run php files on the server not as a downloadable file !
location ~ \.php$ {
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
try_files $uri /index.php =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# lots of the lines below can be included in the following file(s)
include fastcgi.conf;
include snippets/fastcgi-php.conf;
fastcgi_intercept_errors on;
# the fastci_index is included via the snippets/fastcgi_php.conf file so is not needed here
# the line is left here for reference
#fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# can run php through a file socket or via an ip
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
#WPMU Files
location ~ ^/files/(.*)$ {
try_files /wp-content/blogs.dir/$blogid/$uri /wp-includes/ms-files.php?file=$1 ;
access_log off; log_not_found off; expires max;
}
#WPMU x-sendfile to avoid php readfile()
location ^~ /blogs.dir {
internal;
alias /var/www/example.com/htdocs/wp-content/blogs.dir;
access_log off; log_not_found off; expires max;
}
# ensure that no one is able to write directly to the server from the web page.
location ~ /\.ht {
deny all;
}
#add some rules for static content expiry-headers here
}
/etc/nginx/fastcgi.conf
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param REMOTE_USER $remote_user;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
/etc/nginx/fastcgi_params (which is exactly the same as fastcgi.conf ? do I need both ?)
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REQUEST_SCHEME $scheme;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param REMOTE_USER $remote_user;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
/etc/nginx/snippets/fastcgi-php.conf
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# Check that the PHP script exists before passing it
# we do this in the sites config file, so no need for duplication
#try_files $fastcgi_script_name =404;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
#this looks back at the earlier file, does this circular reference cause a problem ?
include fastcgi.conf;
/etc/php/7.4/fpm/php.ini has not been modified from the installed version, and as its rather large, with the exception of the line
cgi.fix_pathinfo = 1
where some guides suggest this should be 0 (zero) and nginx suggest 1, I've tried both values ... and no difference.
Does nginx need a special module to run php to function ?
the file will be downloaded, it makes no difference if I access it from localhost or via its IP address.
Is there something obvious that I am missing ?
I can run the a simpl phpinfo() call from the cli, and I get the expected output.
need more config details... feel free to ask.
thanks in advance
Dave
edit 1
So I've tried all the variations of listen and server_name within the server block that has the php details within it.
I have turned on debug logging in the error file for this site, looking through it states http script var: "/wp-admin/install.php" which seems like it is seeing it as a php script, and demonstrates that it is clearly capturing the correct file. I have also tried with a basic info.php file... here is a section of the log ...
try files handler
2021/10/04 16:21:17 [debug] 452491#452491: *3 http script var: "/info.php"
2021/10/04 16:21:17 [debug] 452491#452491: *3 trying to use file: "/info.php" "/var/www/reslab/wordpress/info.php"
2021/10/04 16:21:17 [debug] 452491#452491: *3 try file uri: "/info.php"
2021/10/04 16:21:17 [debug] 452491#452491: *3 generic phase: 13
2021/10/04 16:21:17 [debug] 452491#452491: *3 content phase: 14
2021/10/04 16:21:17 [debug] 452491#452491: *3 content phase: 15
2021/10/04 16:21:17 [debug] 452491#452491: *3 content phase: 16
2021/10/04 16:21:17 [debug] 452491#452491: *3 content phase: 17
2021/10/04 16:21:17 [debug] 452491#452491: *3 content phase: 18
2021/10/04 16:21:17 [debug] 452491#452491: *3 http filename: "/var/www/reslab/wordpress/info.php"
I feel there should be some clue in here with the server telling me it is recognised as an http script rather than a fastcgi script ?
edit 2
So I just logged onto the server, and ran firefox locally. As I expected it attempts to download the file. However it wants to 'open' it in firefox ... when I do this, it just re-downloads ....
However, when I select the 'other' option from the download list the next windows has a message of :
no applications fournd for application/octet-stream files.
which strikes me as firefox trying to tell me that this is an 'application', or am I missunderstanding FFXs message ?
Also when I do the same thing on my remote pc, I still get the 'open with geany' option.
edit 3
So it occured to me this may be a permissions issue. So I ran the info.php script from the terminal as the www-data (user and group) :
sudo su -s /bin/bash -c "php info.php" -g www-data www-data
and I got the expected output.
note when I did this logged in via ssh to the server.
My other feeling is that the includes aren't correct in some way ? is there a way to debug the files that are being inlcuded (something like nginx -t but with a more verbose output ?)
First off, this is far too much config to trouble shoot for a simple problem, it would be far easier to whittle it down to a minimal config that works and then add in other site, caching, whatever.
But on a quick scan, the server block that does the fastcgi_pass has no listen directive, so there would be no way to hit that config.
Also:
Q: "Does nginx need a special module to run php to function ?"
A: No, not specifically for php. FastCGI is the module your using to contact php via standard protocol.
I do not know why do you change nginx.conf, I usually don't do that. I edit configs in sites available:
Maybe you should try my nginx.conf:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
Then in sites_available place the config from my blog:
server {
# https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-20-04
listen 80;
server_name wordpress.darius;
root /home/darius/Private/Projects/wordpress;
index index.html index.htm index.php;
location / {
# https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-lemp-on-ubuntu-20-04#prerequisites
try_files $uri $uri/ /index.php$is_args$args;
# end https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-lemp-on-ubuntu-20-04#prerequisites
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
# end https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-20-04
# https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-lemp-on-ubuntu-20-04#prerequisites
location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; allow all; }
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
expires max;
log_not_found off;
}
#end https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-lemp-on-ubuntu-20-04#prerequisites
}
In fastcgi.conf the difference I see that in your file there is
fastcgi_param REMOTE_USER $remote_user;
but in my there is no such line. Same with /etc/nginx/fastcgi_params
There are little differences from your in fastcgi-php.conf, my file looks like this:
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi.conf;
Also I am not changing this file ever I think.
cgi.fix_pathinfo in my case is On.
Not sure if there can be problem with the order of includes, since I do not modify those configs, besides ones in sites-available dir.
So try with my configs. And then if that works, make changes little by little to match your needs. Then you should find exactly which part makes it not work.
As you can see I use php 8 so I reccomend it to you also, or change values in my configs examples.
I am hosting multiple php slim applications on the same server. They are located at the path apis/'tier'/'organization'/'appName'/'version' so for example apis/FreeTierSmall/master/exampleApp/v1.
I am using Nginx with php-fpm and am getting a very weird bug. I am trying to redirect any requests that start with apis/master/ to apis/FreeTierSmall/master. I've turned on the Nginx rewrite_log and can see that the files get redirected correctly. I get the correct result if I try apis/FreeTierSmall/master/example/v1. However, I get a 404 error if I try apis/master/example/v1 which redirects to the same php file. I know the redirect is working because I can see it in the logs. It seems that there is some problem with php-fpm. I am adding a header to the php-fpm execution so I know that it is calling the correct script. For some reason though a request of the same file is producing a 404 error in one case and not the other.
Is there some parameter that could cause the same file passed to fpm to work in one instance and not the other?
Here is my nginx configuration:
worker_processes 1;
pid /run/nginx.pid;
user nginx www-data;
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'
'FPM - $document_root - $fastcgi_script_name > $request';
access_log /var/log/nginx/access.log main_timed;
# error_log /dev/stderr notice;
error_log /var/log/nginx/error.log debug;
# error_log above can be debug
rewrite_log on;
keepalive_timeout 65;
server {
listen [::]:80 default_server;
listen 80 default_server;
server_name _;
sendfile off;
root /var/www/html;
index index.php index.html;
error_page 404 /404.html;
# NOTE: Once you use last, that is the last redirect you can do. You must find the file after that.
# HEALTH CHECK
location /apis/FreeTierSmall/elb-status {
access_log off;
return 200 'A-OK!';
# because default content-type is application/octet-stream,
# browser will offer to "save the file"...
# the next line allows you to see it in the browser so you can test
add_header Content-Type text/plain;
}
# NORMAL API PATHS
location /apis/ {
#rewrite the old apis
rewrite ^/apis/master/([\w-]+)/([\w-]+)(.*)$ /apis/FreeTierSmall/master/$1/$2/api.php$3 last;
rewrite ^/apis/interfaceop/([\w-]+)/([\w-]+)(.*)$ /apis/FreeTierSmall/interfaceop/$1/$2/api.php$3 last;
# add api.php to the path of the file
rewrite ^/apis/([\w-]+)/([\w-]+)/([\w-]+)/([\w-]+)(.*)$ /apis/$1/$2/$3/$4/api.php$5 last;
}
# ANY OTHER FILES
location / {
# try to serve the file, the directory, or a 404 error
add_header X-debug-message-2 "A static file was served or 404 error $uri" always;
try_files $uri $uri/ /robots.txt; # Need to change back to =404
}
# ERRORS
# 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;
}
# PHP FILES
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php {
add_header X-debug-message-5 "fastCGI -> .php $document_root$fastcgi_script_name" always;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_read_timeout 300;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
# SECURITY CONCERNS
# deny access to . files, for security
location ~ /\. {
log_not_found off;
deny all;
}
}
}
Turns out, the issue is that the URI of the request doesn't get changed with rewrite. Slim was providing the 404 error because the route didn't exist, and the route didn't exist because the URI never got changed by rewrite. So, rewrite doesn't actually change the request parameters it's just used to decide what file is going to be served. This is ok for most use cases but horrible for apis... a very odd error to debug. Good luck whoever runs into this in the future.
The solution: use proxy_pass.
location /apis/master/ {
# Reroutes /apis/master/* to /apis/FreeTierSmall/master/* correctly!
proxy_pass http://localhost:80/apis/FreeTierSmall/master/;
}
I have problem with setting up my docker environment on remote machine.
I prepared local docker machines. Problem is with nginx + php-fpm.
Nginx act as nginx user, php-fpm act as www-data user. Files on host machine (application files) are owned by user1. chmods are default for symfony2 application.
When I access my webserver it returns 404 error or just simple "file not found".
For a while exact same configuration works on my local Ubuntu 16.04, but fails on Debian Jessie on server. Right now it doesn't work on both. I tried everything, asked on sysops groups and googled for hours. Do you hve any idea?
Here is my vhost configuration
server {
listen 80;
server_name dev.xxxxx.co xxxxx.dev;
root /usr/share/www/co.xxxxx.dev/web;
index app_dev.php;
client_max_body_size 100M;
fastcgi_read_timeout 1800;
location / {
# try to serve file directly, fallback to app.php
try_files $uri $uri/ /app.php$is_args$args;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
access_log off;
}
location ~ ^/(app_dev|config)\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass php-fpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/app.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
location ~ \.php$ {
return 404;
}
}
nginx configuration
user root;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
And my docker compose
version: '2'
services:
nginx:
image: nginx
ports:
- 8082:80
volumes:
- /home/konrad/Workspace:/usr/share/www:ro
- ./conf/nginx.conf:/etc/nginx/nginx.conf:ro
- ./sites:/etc/nginx/conf.d:ro
php-fpm:
image: php:fpm
ports:
- 9000:9000
volumes:
- /home/konrad/Workspace:/usr/share/www
- ./conf/www.conf:/etc/php/7.0/fpm/pool.d/www.conf
- ./conf/php.ini:/usr/local/etc/php/conf.d/90-php.ini:ro
On remote server files are accesible, visible as property of 1001:1001
I have 1 local haproxy server (10.10.1.18) that is used for loadbalance 2 nginx local webservers (web1=10.10.1.21,web2=10.10.1.22).
I can reach local ips of web servers to the index.php file successfully like that http://10.10.1.21/ and http://10.10.1.22/
However, when I point local ip of haproxy http://10.10.1.18/, it only brings the index.html file instead of index.php file. We also have a domainname that points the public ip to the haproxy but http://example.uni.edu brings again the index.html file and not index.php file
So I don't think it's about public vs local ip but rather haproxy or nginx configuration
/etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 10000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
#use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 10000
#---------------------------------------------------------------------
#HAProxy statistics backend
#---------------------------------------------------------------------
listen haproxy3-monitoring *:80
mode http
option forwardfor except 127.0.0.1
option httpclose
stats enable
stats show-legends
stats refresh 5s
stats uri /stats
stats realm Haproxy\ Statistics
stats auth username:password
stats admin if TRUE
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main
bind *:80
default_backend webapp-main
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend webapp-main
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ example.uni.edu
server web1 10.10.1.21:80 check
server web2 10.10.1.22:80 check
web1 nginx - /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name 10.10.1.21;
# note that these lines are originally from the "location /" block
root /usr/share/nginx/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location /dataroot/ {
internal;
alias /var/moodledata/; # ensure the path ends with /
}
location /cachedir/ {
internal;
alias /var/moodledata/cache/; # ensure the path ends with /
}
location /localcachedir/ {
internal;
alias /var/moodledata/localcache/; # ensure the path ends with /
}
location /tempdir/ {
internal;
alias /var/moodledata/temp/; # ensure the path ends with /
}
location /filedir/ {
internal;
alias /var/moodledata/filedir/; # ensure the path ends with /
}
}
web2 has the same configs as web1 along with its own local ip.
When I point directly the index.php http://10.10.1.18/index.php it downloads the index.php file and gives
503 Service Unavailable
Anybody has similar experience issues like this?
Finally it worked out, please follow these steps:
do not use config files under /etc/nginx/conf.d/ only use 1 config file /etc/nginx/nginx.conf like this
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 8192;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
tcp_nopush on;
sendfile on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 512m;
large_client_header_buffers 2 1k;
client_body_timeout 1200;
client_header_timeout 1200;
send_timeout 100;
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name example.uni.edu;
# note that these lines are originally from the "location /" block
root /usr/share/nginx/html;
index index.php index.html index.htm;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ =404;
index index.php;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ [^/]\.php(/|$) {
root /usr/share/nginx/html;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
#fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
###################### For Moodle Application ##################
location /dataroot/ {
internal;
alias /var/moodledata/; # ensure the path ends with /
}
location /cachedir/ {
internal;
alias /var/moodledata/cache/; # ensure the path ends with /
}
location /localcachedir/ {
internal;
alias /var/moodledata/localcache/; # ensure the path ends with /
}
location /tempdir/ {
internal;
alias /var/moodledata/temp/; # ensure the path ends with /
}
location /filedir/ {
internal;
alias /var/moodledata/filedir/; # ensure the path ends with /
}
###################### For Moodle Application ##################
}
}
Make sure you use a valid haproxy config along with 2 different ports 80 is for backend and 8080 is to monitor the stats
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 10000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
#use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 10000
#---------------------------------------------------------------------
#HAProxy statistics backend
#---------------------------------------------------------------------
listen haproxy3-monitoring *:8080
mode http
option forwardfor
option httpclose
stats enable
stats show-legends
stats refresh 5s
stats uri /stats
stats realm Haproxy\ Statistics
stats auth username:password
stats admin if TRUE
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main
bind *:80
option http-server-close
option forwardfor
default_backend webapp-main
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend webapp-main
balance source
option httpchk HEAD / HTTP/1.1\r\nHost:\ example.uni.edu
server web1 10.10.1.21:80 check
server web2 10.10.1.22:80 check
Now you are fine to lookup your stats http://10.10.1.18:8080/ or http://example.uni.edu:8080/
You can also browse your application http://example.uni.edu
Note: Make sure you public ip points to your haproxy server successfully!
I'm fairly new to Nginx, and I'm working on converting an .htaccess file into something nginx can make sense of. Everything's working well (mostly) - I can pull up the homepage just fine. The problem is when I get to a post page.
think similar to wordpress, URLs like:
http://www.example.com/12/post-title-in-slug-form
Where 12 is the post id, and obviously that string is the post slug. I'm trying to parse those as two separate arguments (id & slug) and pass them into index.php like I was successfully doing in apache. I'm getting a 404 page, though, and have confirmed it is because of the rewriterule. Here's what the entire config file looks like, with only the website name changed (for privacy):
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
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 text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
##
# nginx-naxsi config
##
# Uncomment it if you installed nginx-naxsi
##
#include /etc/nginx/naxsi_core.rules;
##
# nginx-passenger config
##
# Uncomment it if you installed nginx-passenger
##
#passenger_root /usr;
#passenger_ruby /usr/bin/ruby;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 80;
server_name example.com;
access_log off;
error_log on;
# deny access to .XYZ files
location ~ /\. {
return 403;
}
location ~ sitemap\.xml {
return 301 http://example.com/sitemap.php;
}
location ~ .php$ {
# Here you have to decide how to handle php
# Generic example configs below
# Uncomment and fix up one of the two options
# Option 1: Use FastCGI
fastcgi_index index.php;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
location / {
try_files $uri $uri/ #router;
}
location #router {
rewrite ^/([0-9]+)/?(.*)?/?$ /index.php?id=$1&slug=$2 last;
}
}
}
Please let me know if you can spot what's throwing it off when it comes to parsing the individual posts into ids and slugs and passing them. Thanks!
You should add a / in the beginning and a / before index.php like this :
rewrite ^/([0-9]+)/?(.*)?/?$ /index.php?id=$1&slug=$2 last;
Note i also used $1 and $2
If what you posted is indeed the COMPLETE config file, then the setup is missing something to handle PHP files as the regexp looks to be fine.
I actually think the config you posted cannot be the full one or that there is something fundamental going on as that config should have thrown errors and failed to load and also, since you mentioned that your PHP was loading fine, then it cannot be the posted config serving your website.
A better config is attached below:
FYI, try_files ABC XYZ last; is not valid syntax and you need at least two options in try_files. Anyway, fixed those in the posted config as well.
server {
listen 80;
server_name example.com;
access_log off;
error_log on;
# deny access to .XYZ files
location ~ /\. {
return 403;
}
location ~ sitemap\.xml {
return 301 http://example.com/sitemap.php;
}
location ~ .php$ {
# Here you have to decide how to handle php
# Generic example configs below
# Uncomment and fix up one of the two options
# Option 1: Use FastCGI
#fastcgi_index index.php;
#include fastcgi_params;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
# Option 2: Pass to Apache
# Proxy_pass localhost:APACHE_PORT
}
location / {
try_files $uri $uri/ #router;
}
location #router {
rewrite ^/([0-9]+)/?(.*)/?$ /index.php?id=$1&slug=$2 last;
}
}
You will need to fix the PHP handling bit and choose which setup you want to implement.
I think though that you need to verify that you only have one instance of nginx running and that it is what is serving your site.