How can i deploy my website on Heroku properly? - php

I've trying to deploy my website on Heroku, the implementation that i used for this it's Model View Controller with PHP. I don't know what happend but when i try to access to the main page (or index) this works perfectly, when i'm trying to access other pages on mi website something occurs like this:
enter image description here
I know one reason which this is happening, i used in my Router the next:
$currentURL = $_SERVER['PATH_INFO'] ?? '/';
//var_dump($_SERVER);
$method = $_SERVER['REQUEST_METHOD'];
if($method === 'GET'){
$fn = $this->routesGET[$currentURL] ?? null;
} else{
$fn = $this->routesPOST[$currentURL] ?? null;
}
So, i displayed global variable of PHP $_SERVER on my website and i noticed $_SERVER['PATH_INFO'] doesn't appear on it. So, i guess that the problem comes from Apache's configuration because i use Apache2 and PHP for this. So, i don't know how configure because it's my first time doing this, if you can help me, i'll really thank to you.
Here is my directory:
enter image description here
And, finally my procfile:
web: vendor/bin/heroku-php-apache2 public/

These are the general appliable steps of configuring an MVC-based web application. Presumed web server version for the settings below: Apache HTTP Server v2.4.
1) Block access to all directories and files:
First of all, in the config file of Apache, the access to all directories and files should be blocked by default:
# Do not allow access to the root filesystem.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
# Prevent .htaccess and .htpasswd files from being viewed by Web clients.
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
2) Allow access to a default directory:
The access to a default directory (here /var/www/), supposedly used for projects, should then be allowed:
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
My recommendation: For security reasons, this location should contain only a index.php and a index.html file, each of them displaying a simple "Hello" message. All web projects should be created in other directories and the access to them should be set separately, as described below.
3) Set access to a separate project directory:
Let's suppose that you create your project in another location (like in the directory /path/to/my/sample/mvc/) than the default one (/var/www/). Then, taking into consideration, that only the subfolder public should be accessible from outside, create a web server configuration for it, like this:
ServerName www.my-sample-mvc.com
DocumentRoot "/path/to/my/sample/mvc/public"
<Directory "/path/to/my/sample/mvc/public">
Require all granted
# When Options is set to "off", then the RewriteRule directive is forbidden!
Options FollowSymLinks
# Activate rewriting engine.
RewriteEngine On
# Allow pin-pointing to index.php using RewriteRule.
RewriteBase /
# Rewrite url only if no physical folder name is given in url.
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite url only if no physical file name is given in url.
RewriteCond %{REQUEST_FILENAME} !-f
# Parse the request through index.php.
RewriteRule ^(.*)$ index.php [QSA,L]
</Directory>
Note that the above settings can be defined either:
in the config file of Apache, or
in a .htaccess file inside the project, or
in a virtual host definition file.
In case a virtual host definition file is used, the settings must be included between the tags <VirtualHost> and </VirtualHost>:
<VirtualHost *:80>
... here come the settings ...
</VirtualHost>
Note: Don't forget to restart the web server after each change of the configuration settings.
Some resources:
What is Options +FollowSymLinks? (1)
What is Options +FollowSymLinks? (2)
RewriteRule Flags
Exposed folders in MVC application
mod_rewrite: what does this RewriteRule do?

Related

Codeigniter Routes not Working under HTTPS

I'm having what seems to be a common problem deploying a codeigniter web app to an Amazon AWS EC2 instance and configuring it for SSL/TLS.
The app is running on an Amazon Linux 2 AMI (HVM) instance.
The web app works fine under HTTP i.e. the basic URL will load the index.php with the default route. The codeigniter routes all call the controller functions fine and load the respective views and any functions on the page that use AJAX to call a controller function all work fine.
When trying with HTTPS the basic URL will load the index.php with the default route, however when adding routes to the end of the URL I encounter a 404 not found error.
Not Found
The requested URL was not found on this server.
The same is true with any functions on the page that use AJAX to call a controller function:
Request URL: https://www.mysite.co.uk/Home/test_fn
Request Method: POST
Status Code: 404 Not Found
Remote Address: xx.xxx.xxx.xx:443
Referrer Policy: strict-origin-when-cross-origin
I've been following the guide here: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-ami.html and have:
Enabled mod_ssl
Used Route 53 to set up the DNS records for my domain
Have a CA-signed certificate (90 day certificate from ZeroSSL)
Placed the certificate in /etc/pki/tls/certs
Placed the key in /etc/pki/tls/private
Updated SSLCertificateFile and SSLCertificateKeyFile in ssl.conf accordingly
Loading the index page under HTTPS (https://www.mysite.co.uk) in a browser works fine. All of the elements are loaded (css and images) and I see the closed padlock symbol in the address bar. Clicking on it states the connection is secure and the certificate is valid, so it appears the configuration there is OK.
In addition:
I've updated the vhost with an entry for port 443:
<VirtualHost *:80>
ServerAdmin webmaster#dummy-host.example.com
DocumentRoot "/var/www/html/myApp"
ServerName https://www.mysite.co.uk/
<Directory "/var/www/html/myApp">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster#dummy-host.example.com
DocumentRoot "/var/www/html/myApp"
SSLEngine on
SSLCertificateFile "/etc/pki/tls/certs/certificate.crt"
SSLCertificateKeyFile "/etc/pki/tls/private/private.key"
ServerName https://www.mysite.co.uk/
<Directory "/var/www/html/myApp">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
The .htaccess file is as follows:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$0 [L]
</IfModule>
I've tried the config.php file with base_url settings of:
$config['base_url'] = 'https://www.mysite.co.uk';
as opposed to the original
$config['base_url'] = 'http://www.mysite.co.uk';
The values for index_page and uri_protocol are:
$config['index_page'] = '';
$config['uri_protocol'] = 'REQUEST_URI';
Controller names have initial characters in uppercase, and as things are working with HTTP in a linux environment I can discount case sensitivity being an issue. Likewise as the routes work under HTTP I don't think it is an issue with the routes.php file:
$route['default_controller'] = 'Home';
$route['home'] = 'Home';
$route['404_override'] = '';
$route['translate_uri_dashes'] = FALSE;
$route['companies'] = 'Company_c/view_companies';
$route['users'] = 'User_c/view_users';
$route['layers'] = 'Layer_c/view_layers';
I've tried many permutations for the .htaccess file.
I'm sure there is something I'm missing somewhere but have been going around in circles for he last few days to no avail.
Is there anything obvious I've missed somewhere along the line? Any assistance greatly appreciated.
I deployed a fresh CI4 with a custom domain on a fresh beanstalk instance. I used amazon certificate. Never used SSH. All done through web interface.
Only changes I did on codeigniter
copied .htaccess and index.php from /public to root folder
altered $pathsConfig in index.php to point project subfolder
altered $baseURL in Config\App.php and added https://
This should run with no problem.
What I suspect is ssl is not configured properly and it points to another virtual host or the default apache directory.
Try creating a regular file in the root folder /test.php and try to access it. If you still get 404 error then your virtual host configuration is broken.
Thanks #Ergec, it does look like a virtual host issue. It can't be picking up the vhost.conf file correctly.
Adding the virtual host section for port 443 to then end of httpd.conf and restarting the service has done the trick.

PHP script in aliased directory mistakenly handled by WSGI when using mod_rewrite

all. So I'm running Apache 2.2. I have a single VirtualHost that's used for a Django application (by way of mod_wsgi) as well as a PHP one that lives in a subdirectory. Normally, this is no problem. You can just Alias /subdir /path/to/phpapp followed by WSGIScriptAlias / /path/to/django.wsgi.
But, the complication is that this PHP application uses mod_rewrite to implement "Fancy URLs," which just means that '/subdir/foo/bar' will get rewritten to something like '/subdir/index.php?path=foo/bar'.
Here's my configuration:
<VirtualHost *:80>
ServerName [snip]
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
Alias /phpapp/ /home/ubuntu/phpapp/
<Directory /home/ubuntu/phpapp>
Order allow,deny
Allow from all
RewriteEngine on
RewriteCond $1 !^(index\.php|img|bin)
RewriteRule ^(.*)$ index.php?__dingo_page=$1 [PT]
</Directory>
WSGIDaemonProcess foo user=ubuntu
WSGIProcessGroup foo
WSGIScriptAlias / /home/ubuntu/djangoapp/apache/django.wsgi
<Directory /home/ubuntu/djangoapp/apache>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
The problem is that whenever a rewrite takes place (e.g., I try to go to /phpapp or /phpapp/foo) the request gets handled by WSGI and I see my Django site's 404 page. If the address passes through (e.g., I go to /phpapp/index.php) then it is handled by PHP and works normally. I thought maybe that adding the [PT] flag to my RewriteRule would fix this problem, but it doesn't seem to have any effect on which handler is chosen. I've also tried SetHandler application/x-httpd-php in the Directory section for the PHP app.
I need the Django application to continue to handle any URLs that aren't specifically aliased to something else. There must be a way to make this work! Thanks.
Using /phpapp wouldn't ever work because you have a trailing slash on that path for the Alias directive. Use:
Alias /phpapp /home/ubuntu/phpapp
By rights that Alias directive should then take precedence over WSGIScriptAlias for the sub URL.
I would suggest you enable logging by mod_rewrite and verify what the URL is being written to. So long as the rewritten URL still sits below /phpapp, it should be fine.
The alternative is to not use WSGIScriptAlias, but use the scheme as outline towards the end of:
http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#The_Apache_Alias_Directive
That allows you to set things up so that the Python web application will only be used as a fallback if no static resource, including PHP, could be mapped.

Cakephp assets not fetching from webroot folder.. missing js & css,

I've been building on localhost and all this stuff works perfectly. Now trying to load the site on a shared host. I've worked through most of the issues and actually have a working site but without any css.
Layout:
My app is in: /home/cake/app
public_html is in: /home/public_html
In public_html/index.php, the only way I was able to get rid of missing file errors was to do this...
require '../cake/app/webroot' . DIRECTORY_SEPARATOR . 'index.php';
The .htaccess in public_html:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
My app was baked from the command line.
All of the index.php and .htaccess files up through the chain are untouched.
/cake
/cake/webroot
/cake/app
/cake/app/webroot
It just can't find the path to all the css and js files.
in my default.ctp, I used the standard html helper links.
echo $this->Html->css('default');
I'm at the end of the proverbial rope. Any help appreciated.
On localhost, I point the apache directory at /cake/app, but I'm pretty sure I don't have access to apache config files on a shared host, hence the reason I pointed the public_html index.php at /cake/app. Probably not right, but it felt like I was moving in the right direction since the site started working.
All your CSS & JS should be inside the app/webroot directory.
It sounds like you've setup your virtual hosts incorrectly. (This is why the CSS works in public_html but not in the webroot directory).
Basically, We only allow access to our application through app/webroot/. This will load the index.php inside the webroot which is provided by cakePHP to load the controllers for every request.
Your virtual host file should look like this:
<VirtualHost *:80>
# Correct: Notice the "/app/webroot/"
DocumentRoot "/path/to/app/public_html/app/webroot/"
# Below is INCORRECT
# Incorrect: DocumentRoot "/path/to/app/public_html/app/"
ServerName yourdomain.com
</VirtualHost>
Now.. the ONLY directory accessible from the outside world is everything in webroot, this can be JS, CSS, Images, Files or whatever other assets you require.
This is how it should be setup, you dont want people to be able to access files outside of your webroot (ie all other CakePHP files).
On shared hosting providers, you will require a slightly different setup (you wont have access to the vhosts of the shared server). This explains the slightly different directory structure the OP has said. Read here for more info on deploying cakephp on a shared host.
http://bakery.cakephp.org/articles/gedm/2009/08/29/installing-cakephp-on-shared-hosting
Instead of including the index.php from the webroot in another index.php (inside your public_html), consider changing the webroot folder entirley to your public_html.
View here for more info on change cakephp webroot folder: CAKEPHP - Change default path to webroot
Change AllowOverride none to AllowOverride FileInfo in /etc/apache2/sites-available/default.
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /home/user/app/
<Directory />
Options FollowSymLinks
AllowOverride FileInfo
</Directory>
<Directory /home/user/app/>
Options Indexes FollowSymLinks MultiViews
AllowOverride FileInfo
Order allow,deny
allow from all
</Directory>
It worked for me.
Finally this one was the command wich worked for me to enable mod_rewrite:
$ a2enmod rewrite
Well, not sure whether this is all "right" or not, but I copied all the folders with the css and js files into public_html, which kind of makes sense. All of those assets need to be publicly accessible. Site works now.

What is Options +FollowSymLinks?

I am using a Lamp server on my computer. I started to use Laravel php framework.
In my .htaccess , If I use Options +FollowSymLinks , I get 500 error.
And If I comment out , I have to use index.php in my all addresses ..example:
/~ytsejam/blog/public/index.php/login
I use Arch Linux . Is there a way to solve it?
edit: I solved this by using virtual hosts. And deleting index.php from application/config/application.php in laravel folder.
You might try searching the internet for ".htaccess Options not allowed here".
A suggestion I found (using google) is:
Check to make sure that your httpd.conf file has AllowOverride All.
A .htaccess file that works for me on Mint Linux (placed in the Laravel /public folder):
# Apache configuration file
# http://httpd.apache.org/docs/2.2/mod/quickreference.html
# Turning on the rewrite engine is necessary for the following rules and
# features. "+FollowSymLinks" must be enabled for this to work symbolically.
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
</IfModule>
# For all files not found in the file system, reroute the request to the
# "index.php" front controller, keeping the query string intact
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
Hope this helps you. Otherwise you could ask a question on the Laravel forum (http://forums.laravel.com/), there are some really helpful people hanging around there.
Parameter Options FollowSymLinks enables you to have a symlink in your webroot pointing to some other file/dir. With this disabled, Apache will refuse to follow such symlink. More secure Options SymLinksIfOwnerMatch can be used instead - this will allow you to link only to other files which you do own.
If you use Options directive in .htaccess with parameter which has been forbidden in main Apache config, server will return HTTP 500 error code.
Allowed .htaccess options are defined by directive AllowOverride in the main Apache config file. To allow symlinks, this directive need to be set to All or Options.
Besides allowing use of symlinks, this directive is also needed to enable mod_rewrite in .htaccess context. But for this, also the more secure SymLinksIfOwnerMatch option can be used.
How does the server know that it should pull image.png from the /pictures folder when you visit the website and browse to the /system/files/images folder in your web browser? A so-called symbolic link is the guy that is responsible for this behavior. Somewhere in your system, there is a symlink that tells your server "If a visitor requests /system/files/images/image.png then show him /pictures/image.png."
And what is the role of the FollowSymLinks setting in this?
FollowSymLinks relates to server security. When dealing with web servers, you can't just leave things undefined. You have to tell who has access to what. The FollowSymLinks setting tells your server whether it should or should not follow symlinks. In other words, if FollowSymLinks was disabled in our case, browsing to the /system/files/images/image.png file would return depending on other settings either the 403 (access forbidden) or 404 (not found) error.
http://www.maxi-pedia.com/FollowSymLinks

Return PHP page based on directory base-name without redirect

I want the server to return a specific PHP page based on the directory name without a redirect. For example:
http://www.example.com/home
should return the same result as:
http://www.example.com/index.php?page=home
but it shouldn't redirect the address
you need to create a special file called '.htaccess' and put it in your web application root directory. File content could be like this:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^/home$ /index.php?page=home [L]
Then configure Apache (httpd.conf, httpd-vhosts.conf) to allow your web application to use that .htaccess config file
<VirtualHost 127.0.0.1:80>
DocumentRoot "/path/to/your/webapp"
ServerName localhost
<Directory "/path/to/your/webapp">
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
This is a good read.
http://httpd.apache.org/docs/current/misc/rewriteguide.html
PHP can't do this without a redirect, but there are a host of solutions:
Use mod_rewrite with apache (.htaccess)
RewriteEngine on
RewriteRule ^home$ /index.php?page=home
Another would be to add an index.php to /home thats only function is to include the document root index.php.
look at frameworks like (my favorites) CodeIngniter or Zend, but you are not limited to it or try to reinvent the wheel by buid your own router
If you are using Apache you can look into htaccess scripts. There are a ton of options available through a google search

Categories