ISPConfig Vhost allowing clean URLs in Laravel - vhosts

I have an existing server which is working well hosting a number of sites using nginx and ISPconfig. However I have created a new site and wish to use Laravel.
I've installed Laravel successfully via composer and have got as far as seeing the familiar welcome blade displayed when I visit mywebsite.com/public
What I want to do next is make some clean urls. My experience with vhost files is somewhat limited and I'm having a bit of trouble with the config.
My routes file looks like this
Route::get('/', function () {
return view('welcome');
});
Route::get('/test', function () {
return view('test');
});
and I'd hoped to see mywebsite.com/test display the contents of test.blade.php
I'm aware I need to do some work with the vhost file before I can expect this to work but my experience with vhosts is limited and I'm at a bit of a loss.
My current file looks like this
server {
listen *:80;
server_name mywebsite.com ;
root /var/www/mywebsite.com/web;
index index.html index.htm index.php index.cgi index.pl index.xhtml;
error_page 400 /error/400.html;
error_page 401 /error/401.html;
error_page 403 /error/403.html;
error_page 404 /error/404.html;
error_page 405 /error/405.html;
error_page 500 /error/500.html;
error_page 502 /error/502.html;
error_page 503 /error/503.html;
recursive_error_pages on;
location = /error/400.html {
internal;
}
location = /error/401.html {
internal;
}
location = /error/403.html {
internal;
}
location = /error/404.html {
internal;
}
location = /error/405.html {
internal;
}
location = /error/500.html {
internal;
}
location = /error/502.html {
internal;
}
location = /error/503.html {
internal;
}
error_log /var/log/ispconfig/httpd/mywebsite.com/error.log;
access_log /var/log/ispconfig/httpd/mywebsite.com/access.log combined;
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location /stats/ {
index index.html index.php;
auth_basic "Members Only";
auth_basic_user_file /var/www/clients/client1/web5/web/stats/.htpasswd_stats;
}
location ^~ /awstats-icon {
alias /usr/share/awstats/icon;
}
location ~ \.php$ {
try_files /5e26a1d85cb98f7191261e023385e60d.htm #php;
}
location #php {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/lib/php5-fpm/web5.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
}
}
Now on another server I have this working with this simple directive
server {
root /var/www/public;
index index.php index.html index.htm;
server_name localhost;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
}
But I am limited to what I can do with the vhost on the current server as ISPconfig writes most of it for me and it refuses to write the above config that worked elsewhere. Also I feel editing the file directly will be bad practice, I'd always be on edge that ISPconfig will rewrite the file for me, so I'm not really sure how best to proceed with this.
My options would be to just go ahead and edit the vhost and hope for the best, but if I do that how would I ensure ISPconfig could not overwrite the file without resorting to "hacky" methods?
Alternatively, is there a config I can enter via ISPconfig that will allow rewrites to happen properly in a way that suits Laravel? In this instance, any directive entered would need to take precedence over the ~ .php$ clause as that is written by ISPconfig before any directives entered via the control panel.

I just had the same problem recently. Digging the ISPConfig's sources, I understood it can insert/ merge/ delete location blocks of that default vhosts file. So i did the following:
Sites' menu > choose website > Options
Then I inputed the following on the "nginx Directives" field:
# redirect stuff to the public inner folder
location / {
root {DOCROOT}/public;
try_files /public/$uri /public/$uri/ /public/index.php?$query_string;
}
# merged the stuff people suggests for laravel inside the php block
# mind the 'merge' keyword that did the trick
location ~ \.php$ { ##merge##
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
}

There is a slight problem with Danilo's answer. Php ran but assets like js/css/images stopped loading. Adding the following to nginx directives inside ISPConfig works for me:
location / {
root {DOCROOT}/public;
try_files $uri public/$uri/ /public/index.php?$query_string;
}

I am not expert with this but from my past experience if I have two domains I would define server blocks for each in two different files and place them in /etc/nginx/sites-available/site1.com and /etc/nginx/sites-available/site2.com
but it looks like you already have a website that you access using mywesite.com which is located at /var/www/mywebsite.com/web; (see the root value of your configuration file)
Now you install Laravel in test folder in /var/www/mywebsite.com/test location.
To access this you need can try adding following at the end of your ispconfig file.
Note how I used the relative path to laravel's public folder from the root of the server block.
location /../test/public {
try_files $uri $uri/ /index.php$is_args$args;
}
For more detailed tutorial try Nginx Server Block Setup.
Hope this helps,
K

Related

Chrome does not go to localhost website but rather nginx screen

I setup a VM Ubuntu 18.04 and using a LNMP stack. I have my website working and connecting just fine in firefox, but for chrome it just points to the "Welcome to Nginx!" Screen.
I have tried disabling caches, removing anything relating to caches, and browsing in incognito mode. All the stack overflow answerI have found didn't help, which included going to chrome flags and doing some things there.
For the life of me I cannot figure out why it works on Firefox but not Chrome. I just put my website live today and a lot of CSS is off because its chrome based and not FF based. I want to correct it, but working in a non-local environment is driving me crazy.
Below is my nginx setup.
server {
server_name zeragames.localhost;
root /var/www/html/zeragames/web; ## <-- Your only path reference.
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Very rarely should these ever be accessed outside of your lan
location ~* \.(txt|log)$ {
allow 192.168.0.0/16;
deny all;
}
location ~ \..*/.*\.php$ {
return 403;
}
location ~ ^/sites/.*/private/ {
return 403;
}
# Block access to scripts in site files directory
location ~ ^/sites/[^/]+/files/.*\.php$ {
deny all;
}
# Allow "Well-Known URIs" as per RFC 5785
location ~* ^/.well-known/ {
allow all;
}
# Block access to "hidden" files and directories whose names begin with a
# period. This includes directories used by version control systems such
# as Subversion or Git to store control files.
location ~ (^|/)\. {
return 403;
}
location / {
# try_files $uri #rewrite; # For Drupal <= 6
try_files $uri /index.php?$query_string; # For Drupal >= 7
}
location #rewrite {
#rewrite ^/(.*)$ /index.php?q=$1; # For Drupal <= 6
rewrite ^ /index.php; # For Drupal >= 7
}
# Don't allow direct access to PHP files in the vendor directory.
location ~ /vendor/.*\.php$ {
deny all;
return 404;
}
# Protect files and directories from prying eyes.
location ~* \.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|/(\.(?!well-known).*)|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config$|/#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$ {
deny all;
return 404;
}
# In Drupal 8, we must also match new paths where the '.php' appears in
# the middle, such as update.php/selection. The rule we use is strict,
# and only allows this pattern with the update.php front controller.
# This allows legacy path aliases in the form of
# blog/index.php/legacy-path to continue to route to Drupal nodes. If
# you do not have any paths like that, then you might prefer to use a
# laxer rule, such as:
# location ~ \.php(/|$) {
# The laxer rule will continue to work if Drupal uses this new URL
# pattern with front controllers other than update.php in a future
# release.
location ~ '\.php$|^/update.php' {
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
# Ensure the php file exists. Mitigates CVE-2019-11043
try_files $fastcgi_script_name =404;
# Security note: If you're running a version of PHP older than the
# latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini.
# See http://serverfault.com/q/627903/94922 for details.
include fastcgi_params;
# Block httpoxy attacks. See https://httpoxy.org/.
fastcgi_param HTTP_PROXY "";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param QUERY_STRING $query_string;
fastcgi_intercept_errors on;
# PHP 5 socket location.
#fastcgi_pass unix:/var/run/php5-fpm.sock;
# PHP 7 socket location.
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
try_files $uri #rewrite;
expires max;
log_not_found off;
}
# Fighting with Styles? This little gem is amazing.
# location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6
location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7
try_files $uri #rewrite;
}
# Handle private files through Drupal. Private file's path can come
# with a language prefix.
location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7
try_files $uri /index.php?$query_string;
}
# Enforce clean URLs
# Removes index.php from urls like www.example.com/index.php/my-page --> www.example.com/my-page
# Could be done with 301 for permanent or other redirect codes.
if ($request_uri ~* "^(.*/)index\.php/(.*)") {
return 307 $1$2;
}
}

How to host Mediawiki images outside root with an alias, using nginx?

I have a Mediawiki farm and everything works except image display. Image upload works in the sense that they get put in the correct folder along with thumbs, but images don't display. I'd like to keep hosting images outside of site root though.
The Mediawiki installation is in: /var/www/mediawiki
The image folder is in: /var/cats.wiki/images
My nginx config is:
server {
listen 80;
server_name cats.wiki; #made up name for example
root /var/www/mediawiki;
client_max_body_size 100M;
location /images {
alias /var/cats.wiki/images; #relevant part
}
location / {
index index.php;
error_page 404 = #mediawiki;
}
location #mediawiki {
rewrite ^/w([^?]*)(?:\?(.*))? /index.php?title=$1&$2 last;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param MW_INSTALL_PATH /var/www/mediawiki;
fastcgi_param WIKI_PATH "catwiki.php";
}
location ~* \.(js|css|svg|png|jpg|jpeg|gif|ico)$ {
try_files $uri /index.php;
expires 365d;
log_not_found off;
gzip_static on;
gzip_comp_level 5;
access_log off;
add_header Cache-Control private;
}
}
and the relevant section of my LocalSettings, the logo also doesn't display on browser
$wgLogo = "/var/cats.wiki/images/logo.png";
$wgEnableUploads = true;
$wgUseImageMagick = true;
$wgImageMagickConvertCommand = "/usr/bin/convert";
$wgUploadDirectory = "/var/cats.wiki/images";
$wgUploadPath = "/images";
Thanks! :)
It is not clear from your question whether the server directive from your nginx config applies to your whole farm or only one wiki. You definitely can have one server for all wikies; I do in my own wiki farm setup.
In my wiki farm setup, the section for the image folder says (simplified and adapted to your example):
location ~* ^/images(?<image_subpath>/.+)$ {
root $images_root;
try_files $image_subpath #mediawiki;
# ... (some code to neutralise potentially malicious uploads)
}
where $images_root is set previously, in http directive, with a map directive (simplified and adapted to your example):
map $host $images_root {
cats.wiki /var/cats.wiki/images;
dogs.wiki /var/dogs.wiki/images;
# ...
}

Nginx access html resource with or without extension

I want to access HTML resources with or without extension. Currently, I defined two location blocks as defined below.
location = /home {
default_type "text/html";
alias /var/www/html/home.html;
}
location = /home.html {
default_type "text/html";
alias /var/www/html/home.html;
}
How the above configuration should be written in a single location block?
You can use try_files to test for various filename matches, for example:
root /var/www/html;
location / {
try_files $uri $uri.html $uri/ =404;
}
See this document for details.

nginx catchall conf file not catching all

I have a wildcard DNS entry so *.mydomain.tld is directed to my server.
I'm Using nginx
I have 2 conf files titled:
default
myconf.conf
My conf files look like this:
default:
server {
listen 80;
listen [::]:80 default_server ipv6only=on;
root /var/www/website;
index index.html index.htm;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html;
}
}
myconf.conf:
server {
listen 80;
#listen [::]:80 default_server ipv6only=on;
root /home/me/www/website;
index index.php index.html index.htm;
# Make site accessible from http://localhost/
# orig # server_name localhost;
server_name me.mydomain.tld;
access_log /home/me/logs/me.mydomain.tld.access.log;
error_log /home/me/logs/me.mydomain.tld.error.log warn;
location / {
try_files $uri $uri/ $uri.php?$args;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
When I browse to the domains as follows, these are the conf files that load up.
me.mydomain.tld loads up root directory defined in myconf.conf
mydomain.tld loads up root directory defined in default
anything.mydomain.tld loads up root directory defined in myconf.conf
What is going wrong that default is not being the catchall it should be?
anything.mydomain.tld should be loading the root directory in the default conf file.
In your default config file, you have to specify default_server on both listen lines; also, you need to remove the server_name line:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/website;
index index.html index.htm;
#server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html;
}
}
The underscore that you are using for the server_name is not actually a wild card (if that was your intent). From the nginx Server Names documentation:
There is nothing special about this name, it is just one of a myriad of invalid domain names which never intersect with any real name. Other invalid names like “--” and “!##” may equally be used.

How to set index.html as root file in Nginx?

How to set index.html for the domain name e.g. https://www.example.com/ - leads user to index.html in root directory.
I've tried different things like:
server {
# some configs
location = / {
index index.html;
fastcgi_index index.html;
}
or
location / {
index index.html;
fastcgi_index index.html;
}
}
Nothing helped me.
There are some other configs with location keyword, though I'd commented them either.
Other "location" configs in the server { clause:
location ~ .*(css|htc|js|bmp|jp?g|gif|ico|cur|png|swf|htm?|html)$ {
access_log off;
root $www_root;
}
location ~ \.php$
{
include /etc/nginx/fastcgi_params;
index index.html;
fastcgi_index index.html;
fastcgi_param SCRIPT_FILENAME $www_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass 127.0.0.1:9000;
# Директива определяет что ответы FastCGI-сервера с кодом больше или равные 400
# перенаправлять на обработку nginx'у с помощью директивы error_page
fastcgi_intercept_errors on;
break;
}
location ~ /\.ht {
deny all;
}
All them were commented and uncommented, but nothing helped.
PS Editions were made in /etc/nginx/sites-enabled/domainname.com file.
in your location block you can do:
location / {
try_files $uri $uri/index.html;
}
which will tell ngingx to look for a file with the exact name given first, and if none such file is found it will try uri/index.html. So if a request for https://www.example.com/ comes it it would look for an exact file match first, and not finding that would then check for index.html
location / { is the most general location (with location {). It will match anything, AFAIU. I doubt that it would be useful to have location / { index index.html; } because of a lot of duplicate content for every subdirectory of your site.
The approach with
try_files $uri $uri/index.html index.html;
is bad, as mentioned in a comment above, because it returns index.html for pages which should not exist on your site (any possible $uri will end up in that).
Also, as mentioned in an answer above, there is an internal redirect in the last argument of try_files.
Your approach
location = / {
index index.html;
is also bad, since index makes an internal redirect too. In case you want that, you should be able to handle that in a specific location. Create e.g.
location = /index.html {
as was proposed here. But then you will have a working link http://example.org/index.html, which may be not desired. Another variant, which I use, is:
root /www/my-root;
# http://example.org
# = means exact location
location = / {
try_files /index.html =404;
}
# disable http://example.org/index as a duplicate content
location = /index { return 404; }
# This is a general location.
# (e.g. http://example.org/contacts <- contacts.html)
location / {
# use fastcgi or whatever you need here
# return 404 if doesn't exist
try_files $uri.html =404;
}
P.S. It's extremely easy to debug nginx (if your binary allows that). Just add into the server { block:
error_log /var/log/nginx/debug.log debug;
and see there all internal redirects etc.
The answer is to place the root dir to the location directives:
root /srv/www/ducklington.org/public_html;
According to the documentation
Checks the existence of files in the specified order and uses the first found file for request processing; the processing is performed in the current context. The path to a file is constructed from the file parameter according to the root and alias directives. It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”. If none of the files were found, an internal redirect to the uri specified in the last parameter is made. Important
an internal redirect to the uri specified in the last parameter is
made.
So in last parameter you should add your page or code if first two parameters returns false.
location / {
try_files $uri $uri/index.html index.html;
}
Add this to the location block in nginx works for me
try_files $uri $uri/ /index.html =404;
thats the entire block
location / {
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
root /var/www
try_files $uri $uri/ /index.html =404;
}
For me, the try_files directive in the (currently most voted) answer https://stackoverflow.com/a/11957896/608359 led to rewrite cycles,
*173 rewrite or internal redirection cycle while internally redirecting
I had better luck with the index directive. Note that I used a forward slash before the name, which might or might not be what you want.
server {
listen 443 ssl;
server_name example.com;
root /home/dclo/example;
index /index.html;
error_page 404 /index.html;
# ... ssl configuration
}
In this case, I wanted all paths to lead to /index.html, including when returning a 404.