Symfony4 Assets handle after deployment - assets

I just tried to deploy my app on a server and I have some problems wiht the assets.
I uploaded my app on a subfolder rapp so I have this /var/www/html/rapp
First : I had to change my publicPath on webpackEncore to include /rapp/public to have /rapp/public/build while just /build worked in dev (with the php bin/console server:run command)
is there a way to keep the publicPath inside the public Folder ? why I have to specify the subfolder ?
Second, with the first change It seems I have good URL to get my assets http://domain/rapp/public/build/main.css but it return a 404 for all my assets file (js and css)
I followed the recommended VHost (changed for some tests)
<VirtualHost *:80>
#ServerName domain.tld
#ServerAlias www.domain.tld
DocumentRoot /var/www/html/rapp/public
<Directory /var/www/html/rapp/public>
AllowOverride All
Order Allow,Deny
Allow from All
</Directory>
# uncomment the following lines if you install assets as symlinks
# or run into problems when compiling LESS/Sass/CoffeeScript assets
# <Directory /var/www/project>
# Options FollowSymlinks
# </Directory>
ErrorLog /var/log/apache2/project_error.log
CustomLog /var/log/apache2/project_access.log combined
</VirtualHost>
edit : added .htaccess on my root app folder and public app folder
root app folder:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule !\.(js|gif|jpg|png|css|txt)$ public/index.php [L]
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
and public app folder
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /rapp/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
and here is my webpack encore config
// webpack.config.js
var Encore = require('#symfony/webpack-encore');
Encore
// the project directory where all compiled assets will be stored
.setOutputPath('public/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('/rapp/public/build')
// will create public/build/main.js and public/build/main.css
.addEntry('main', './assets/js/main.js')
//Add entry if other js/css needed. first parameter is the generated filename.
.addEntry('reader', './assets/js/reader.js')
//file upload with dropzone
.addEntry('dropzone', './assets/js/dropzone.js')
//Admin chapter js
.addEntry('admin-chapter', './assets/js/chapter.js')
// allow sass/scss files to be processed
.enableSassLoader()
// allow legacy applications to use $/jQuery as a global variable
.autoProvidejQuery()
.enableSourceMaps(!Encore.isProduction())
// empty the outputPath dir before each build
.cleanupOutputBeforeBuild()
// create hashed filenames (e.g. app.abc123.css)
.enableVersioning()
.createSharedEntry('vendor', [
'jquery',
])
.configureFilenames({
images: '[path][name].[hash:8].[ext]'
})
;
// export the final configuration
module.exports = Encore.getWebpackConfig();
(I launched the Encore build with dev option, not production)
the manifest.json is created, all the files with versioning are created, but as the file request is without versionning, it seems it's not found.
I just started with webpack with this project so i'm a complete noob, and I don't know much about apache/htaccess config, so maybe I miss something obvious...
If I'm unclear with something, let me know it's quite late here and I can't think properly anymore ^^"
edit : I changed my vhost config (on a conf file : /etc/apache2/sites-enabled/rapp.conf) and htaccess on my app folders (root and public)
I still not working though.

As described in the Symfony Configuring a Web Server documentation. Your Apache virtual host file should look like this
<VirtualHost *:80>
#ServerName domain.tld
#this tells Apache to load http://domain.tld from the specified directory
DocumentRoot /var/www/html/rapp/public
#this sets the access rules of the directory
<Directory /var/www/html/rapp/public>
AllowOverride All
Order Allow,Deny
Allow from All
#for Apache 2.4 replace the Allow entries above with this line
#Require all granted
#this is what loads symfony at http://domain.tld/route
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
</Directory>
#this allows the use of bin/console assets:install --symlink
#which is executed when you run composer.phar install
#which should not be needed since you use webpack for asset management
#<Directory /var/www/html/rapp>
# Options +FollowSymlinks
#</Directory>
#this prevents routing from being executed on `http://domain.ltd/bundles/file.ext`
#resulting in a simple 404
<Directory /var/www/html/rapp/public/bundles>
<IfModule mod_rewrite.c>
RewriteEngine Off
</IfModule>
</Directory>
#this prevents routing from being executed on `http://domain.ltd/build/file.ext`
#resulting in a simple 404
<Directory /var/www/html/rapp/public/build>
<IfModule mod_rewrite.c>
RewriteEngine Off
</IfModule>
</Directory>
# optionally set the value of the environment variables used in the application
#SetEnv APP_ENV prod
#SetEnv APP_SECRET <app-secret-id>
#SetEnv DATABASE_URL "mysql://db_user:db_pass#host:3306/db_name"
ErrorLog /var/log/apache2/project_error.log
CustomLog /var/log/apache2/project_access.log combined
</VirtualHost>
Your webpack config should look like
// webpack.config.js
var Encore = require('#symfony/webpack-encore');
Encore
// the project directory where all compiled assets will be stored
.setOutputPath('public/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('/build')
//...
;
Then delete your .htaccess files as they should not be needed.
Process new configurations
Afterward restart your Apache server to load the new vhost configuration.
Then delete your /var/www/html/rapp/var/cache/prod and/or /var/www/html/rapp/var/cache/dev directories.
Open a terminal on the server and navigate to /var/www/html/rapp.
Then run php composer.phar install --no-dev --optimize-autoloader
This should also execute symfony cache:clear and assets:intall
Then run yarn build which will process your assets to the /var/www/html/rapp/public/build directory.
However I strongly suggest deploying the production built files from public/build as opposed to installing node.js and webpack on the production server. As suggested in the Symfony Documentation on How do I deploy my Encore Assets?
End Result:
navigating to http://domain.ltd will load your application from /var/www/html/rapp/public/index.php
routes will be generated as http://domain.ltd/route
webpack will output the files using the working directory /var/www/html/rapp where your Symfony app lives
absolute url assets will be loaded as http://domain.ltd/build/asset.ext
As for webpack versioning of your assets, ensure you update your production framework configuration to load the manifest.json file as follows:
#/var/www/html/rapp/config/packages/framework.yml
framework:
#...
assets:
json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'
#...

Related

Symfony 5 routing with annotations doesn't work with Apache and Docker

I'm trying to make a Symfony 5 app running in a Docker (version 19.03.8) with Apache.
I have an issue with the routing of the applications using annotations, Symfony always returns the error Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "No route found for "GET /test2"" at /app/vendor/symfony/http-kernel/EventListener/RouterListener.php line 136
It seems to be environment related because it works properly when I use the symfony local web server and when I use a xampp installation in windows.
A really weird thing is that I only get the error if I use the annotations, if I configure my routes with the routes.yaml file it works fine.
I installed the annotations with composer require annotations and the symfony apache-pack with composer require symfony/apache-pack, which created the .htaccess file in my public folder
# Use the front controller as index file. It serves as a fallback solution when
# every other rewrite/redirect fails (e.g. in an aliased environment without
# mod_rewrite). Additionally, this reduces the matching process for the
# start page (path "/") because otherwise Apache will apply the rewriting rules
# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl).
DirectoryIndex index.php
# By default, Apache does not evaluate symbolic links if you did not enable this
# feature in your server configuration. Uncomment the following line if you
# install assets as symlinks or if you experience problems related to symlinks
# when compiling LESS/Sass/CoffeScript assets.
# Options FollowSymlinks
# Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve
# to the front controller "/index.php" but be rewritten to "/index.php/index".
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
# Determine the RewriteBase automatically and set it as environment variable.
# If you are using Apache aliases to do mass virtual hosting or installed the
# project in a subdirectory, the base path will be prepended to allow proper
# resolution of the index.php file and to redirect to the correct URI. It will
# work in environments without path prefix as well, providing a safe, one-size
# fits all solution. But as you do not need it in this case, you can comment
# the following 2 lines to eliminate the overhead.
RewriteCond %{REQUEST_URI}::$0 ^(/.+)/(.*)::\2$
RewriteRule .* - [E=BASE:%1]
# Sets the HTTP_AUTHORIZATION header removed by Apache
RewriteCond %{HTTP:Authorization} .+
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%0]
# Redirect to URI without front controller to prevent duplicate content
# (with and without `/index.php`). Only do this redirect on the initial
# rewrite by Apache and not on subsequent cycles. Otherwise we would get an
# endless redirect loop (request -> rewrite to front controller ->
# redirect -> request -> ...).
# So in case you get a "too many redirects" error or you always get redirected
# to the start page because your Apache does not expose the REDIRECT_STATUS
# environment variable, you have 2 choices:
# - disable this feature by commenting the following 2 lines or
# - use Apache >= 2.3.9 and replace all L flags by END flags and remove the
# following RewriteCond (best solution)
RewriteCond %{ENV:REDIRECT_STATUS} =""
RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
# Rewrite all other queries to the front controller.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ %{ENV:BASE}/index.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
# When mod_rewrite is not available, we instruct a temporary redirect of
# the start page to the front controller explicitly so that the website
# and the generated links can still be used.
RedirectMatch 307 ^/$ /index.php/
# RedirectTemp cannot be used instead
</IfModule>
</IfModule>
This is the content of my controller:
<?php declare(strict_types=1);
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class TestController {
/**
* #Route("/test2", name="test2")
*/
public function test2() {
return new Response('{"hehe": "working?"}', Response::HTTP_OK, ['content-type' => 'application/json']);
}
}
This is the content of my annotations.yml
controllers:
resource: ../../src/Controller/
type: annotation
kernel:
resource: ../../src/Kernel.php
type: annotation
This is my Dockerfile:
FROM php:7.4-apache
ENV COMPOSER_ALLOW_SUPERUSER=1
EXPOSE 80
WORKDIR /app/public
RUN apt-get update && \
apt-get install -y libpq-dev zip unzip && \
docker-php-ext-install pdo pdo_pgsql && \
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
ADD conf/php.ini /usr/local/etc/php/conf.d/app.ini
RUN a2enmod rewrite
ADD conf/vhost.conf /etc/apache2/sites-available/000-default.conf
ADD conf/apache.conf /etc/apache2/conf-available/z-app.conf
RUN a2enconf z-app
RUN chmod -R 755 /app
This is my apache.conf:
DocumentRoot "/app/public"
<Directory "/app/public">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Require all granted
</Directory>
This is my vhost.conf:
<VirtualHost *:80>
DocumentRoot "/app/public"
<Directory "/app/public">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
I tried to clear the cache with php bin/console cache:clear
EDIT: Inside the container the route isn't listed, but if I run php bin/console debug:router outside of the container it works, I have no idea why...
I finally found the issue which was a bug in virtualbox shared folders.
My setup is a Windows 7 host with a linux VM that runs the container.
composer install wasn't working properly because of the shared folders situation (more information https://github.com/laravel/homestead/issues/1240 https://github.com/kylekatarnls/update-helper/issues/3)
I had version 5.X.X of VirtualBox, I upgraded to 6.0.18 and now it's working fine

How to setup apache server for React route?

I have my react app running great on my local dev server but it did not work when I dump my production ready files straight into Apache's htdocs directory:
Here is what I have:
/var/www/index.html
/var/www/bundle.js
and I have
DocumentRoot /var/www
in /etc/apache2/sites-available/000-default.conf
The fact is that
1). when I access http://...com/ that routed me to Login page
2). After I clicked a link
<Link to="main"><button>Log In</button></Link>
the content in the browser location field become:
http://...com/main
3). Now if I reload this url (http://...com/main), I got
The requested URL /main was not found on this server
My rounting in React:
<Router history={browserHistory }>
<Route path="/" component={TopContainer}>
<IndexRoute component={Login} />
<Route path='main' component={MainContainer} />
</Route>
</Router>
What else I am missing in the apache configuration?
thanks
Change the VirtualHost configuration (typically found in /etc/httpd/conf.d\vhosts.conf) by adding the following Rewrite* lines:
<VirtualHost *:8080>
ServerName example.com
DocumentRoot /var/www/httpd/example.com
<Directory "/var/www/httpd/example.com">
...
RewriteEngine On
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
</Directory>
</VirtualHost>
This tells Apache to serve any files that exist, but if they don't exist, just serve /index.html rather than a 404: not found.
Apache Reference: Configuring Apache Virtual Hosts
react-router History Reference: Configuring Your Server
Complete answer gratefully stolen from here
Edit: 'On' need to be uppercase in current apache version
The above solution works for Ubuntu as well but I have struggled a bit with it so here are the steps necessary to make it work.
Location of the file where you need to place the above mentioned configuration is under
/etc/apache2/sites-enabled
default is
/etc/apache2/sites-enabled/000-default.conf
Then you need to make sure that RewriteEngine is running (otherwise you will get an error when restarting Apache server).
sudo a2enmod rewrite
Finally, restart Apache server
sudo /etc/init.d/apache2 restart
Now, it should work.
When you are using default configuration (root of the website is under /var/www/html), then all you need to do is to place
<Directory "/var/www/html">
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
</Directory>
to the above mentioned file under <VirtualHost ...>
If you have to use .htaccess and a sub directory then following works for me.
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
What worked for me, echoing many of the answers and comments here:
sudo a2enmod rewrite
Open up /etc/apache2/apache2.conf
Paste in this with the path to your root:
<Directory "/var/www/PATH_TO_YOUR_ROOT">
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
</Directory>
sudo service apache2 restart
Pasting into the site-specific conf file did not work as earlier answers suggested.
None of the solutions posted so far appear to address the issue where missing ressources incorrectly return 200 instead of 404, which can make debugging when certain files are missing rather annoying.
My solution is to instead watch what type of resource the request expects to recieve, since browsers will ask for HTML when navigating to a page (Firefox asks for text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8) but not when accessing resources after the initial load (JS files imported via <script> or as ES6 modules ask for */*, CSS files ask for text/css,*/*;q=0.1, accessing JSON via the fetch() API will specify application/json, text/plain, */* and so on). By relying on that assumption, one can configure Apache to serve the Single page app when trying to access a non-existent file (such as a route that only works within the Single-page app) without also sending it whenever said SPA asks for a CSS file that has been renamed or a missing JSON file.
EDIT: MDN has a list of common values for the Accept header.
<Directory "/var/www/httpd/example.com">
RewriteEngine on
# Browsers will specifically ask for HTML (among other things) on initial page load
# That is, if the *user* tries to access a *nonexisting* URL, the app is loaded instead
# but if a webpage attempts to load a missing resource it will return 404.
# (You can still go to /myreactapp/favicon.ico, but a missing /myreactapp/favicon.png resource won't return 200)
# if (HTTP_ACCESS.contains('text/html') && file_not_exists(REQUEST_FILENAME))
RewriteCond %{HTTP_ACCEPT} text/html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [last]
# Any ressources loaded by index.html should behave correctly (i.e: Return 404 if missing)
RewriteRule ^ - [last]
AllowOverride None
Options FollowSymLinks Multiviews
Require all granted
</Directory>
Thank you! This worked for me.
I am pasting my config if you are serving multiple sites (virtualhost) and also SSL certificates (SSL was made with certbot), with redirect http to https
This setting works on Linode / Ubuntu
yoursite.com-le-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost *:443>
# Admin email, Server Name (domain name), and any aliases
ServerAdmin webmaster#yoursite.com
ServerName yoursite.com
ServerAlias www.yoursite.com
# Index file and Document Root (where the public files are located)
DirectoryIndex index.html index.php
DocumentRoot /var/www/html/yoursite.com/public_html
<Directory "/var/www/html/yoursite.com/public_html">
RewriteEngine on
# Browsers will specifically ask for HTML (among other things) on initial page load
# That is, if the *user* tries to access a *nonexisting* URL, the app is loaded instead
# but if a webpage attempts to load a missing resource it will return 404.
# (You can still go to /myreactapp/favicon.ico, but a missing /myreactapp/favicon.png resource won't return 200)
# if (HTTP_ACCESS.contains('text/html') && file_not_exists(REQUEST_FILENAME))
RewriteCond %{HTTP_ACCEPT} text/html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [last]
# Any ressources loaded by index.html should behave correctly (i.e: Return 404 if missing)
RewriteRule ^ - [last]
AllowOverride None
Options FollowSymLinks Multiviews
Require all granted
</Directory>
# Log file locations
LogLevel warn
ErrorLog /var/www/html/yoursite.com/log/error.log
CustomLog /var/www/html/yoursite.com/log/access.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/yoursite.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yoursite.com/privkey.pem
</VirtualHost>
</IfModule>
This is what we use at work for our production react app which is using BrowserRouter from react-router:
httpd.conf
<VirtualHost *:3000>
DocumentRoot "/var/www/html"
<Directory /var/www/html/>
Header set Cache-Control "no-cache"
# https://stackoverflow.com/a/34154531/2089675
FallbackResource /index.html
</Directory>
<Directory /var/www/html/static/>
# https://create-react-app.dev/docs/production-build/#static-file-caching
Header set Cache-Control "public, max-age=31536000"
# https://stackoverflow.com/a/54943214/5600537
RequestHeader edit "If-None-Match" '^"((.*)-gzip)"$' '"$1", "$2"'
</Directory>
</VirtualHost>
As you can see most of the comments in there are answers from SO, so I'm just giving back :)
configuration
Place the above file in /usr/local/apache2/conf/httpd.conf.
The config also assumes that you have put the contents of the build folder inside /var/www/html/. If you've placed them elsewhere, then adjust the path accordingly.
ports
The VirtualHost *:3000 part is just for exposing the server's port in the docker container (httpd:buster) used to run it. This is also the same port CRA defaults to in dev. An external proxy is used to manage where the application can be accessed from.
compression
Finally, if you are interested in serving gzipped files you may want to remove the RequestHeader edit line, and then do some more work to make sure .gz files can be served:
ex.
AddOutputFilterByType DEFLATE text/html application/javascript
React routing issue fixed on ubantu server
Solution:
Open the file using the console.
If you are using SSL
nano /etc/apache2/sites-available/000-default-le-ssl.conf
Add the following lines
===================================================================================
DocumentRoot /var/www/project
<Directory "/var/www/project">
RewriteEngine on
RewriteCond %{HTTP_ACCEPT} text/html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [last]
RewriteRule ^ - [last]
AllowOverride None
Options FollowSymLinks Multiviews
Require all granted
Solution:
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
If you've multiple virtual host then follow these steps
Goto to that VH and open the .htaccess file
add these lines and save it
restart the apache service again so that it can reflect into the settings
Go on this directory
/etc/apache2/sites-available
open File : 000-default.conf
Change its permission : 777
Paste code on bottom of file
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
Restart server

Laravel 5 pages are not being displayed on live server

Main Points:
- I am using Laravel 5, apache, and ubuntu
- mysite.com is WORKING
- mysite.com/login works on localhost, but not on live server
I'm building my first website, and my home page is 'live' (it is up and working) My problems arise when I want to create a 'mywebsite/login' page. I am getting a 404 Not Found error on live, when the page works on my local machine.
I believe this is happening because my .htaccess file not rewriting correctly in regards to my folder structure. The problem is I'm not able to figure it out, as this is all new to me.
My document root is /var/www/laravel/public
My .htaccess is in the above folder.
It looks like this
<IfModule mod_rewrite.c>
<IfModule mod_negotians.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
I have a virtual host file for my site in /etc/apache2/sites-available
It's contents look like this
<VirtualHost *:80>
ServerName mysite.com
ServerAlias www.mysite.com
DocumentRoot /var/www/laravel/public
<Directory /var/www/laravel/public>
Options -Indexes +IncludesNOEXEC +FollowSymLinks +ExecCGI
Allow from all
Allowoverride All
</Directory>
RewriteEngine on
<Directory /var/www/laravel>
AllowOverride All
</Directory>
**A few more lines...**
</VirtualHost>
I have also enabled mod_rewrite on the server.
I am thinking that I have a smaller 'pointing' error here somewhere, but I'm not experienced enough with these files to see it. Is there anyone that can give me a hand?
Thanks
Move All the files on xyz(your folder name for which domain/ subdomain is mapped) folder
Then follow these steps
1 – go to public folder
2 – copy .htacsses file(this make your routes work)
3 -paste it in xyz folder
4 change server.php to index.php
5 – enjoy and happy coding
This is working fine with hostgator.in shared hosting.
When you push your code from local to server then sometimes it's not working the same. For that please try following commands. It works for me and I hope it works for everyone as well.
$ sudo chmod 777 -R folderpath //To give 777 permission to your project
$ php artisan config:clear //To remove the configuration cache
$ php artisan view:clear //To remove the views blade cache
$ php artisan route:clear //To remove the route cache
$ php artisan clear-compiled //To clear the compiled classes and services application cache
// If you use passport then:
$ php artisan passport:install
// At last:
$ composer update

How to use DAV and DirectoryIndex in Apache 2.4?

In my apache configuration I have a virtual host configured like this:
Alias /mediamanager /storage/files/mediamanager
<Directory /storage/files/mediamanager>
DirectoryIndex /mediaManagerIndex.php
DAV On
# ... And some authentication directives ... #
</Directory>
The idea is that someone can access the files both by a WebDAV-Client and also a simple web browser in which case some pretty directory view is generated by a PHP script.
That worked great in Apache 2.2, but recently I upgraded to Apache 2.4 and now it is broken. I highly suspect I I suffer from this bug which is already 2 years old and no fix in sight. The proposed workaround to add:
<Limit PROPFIND>
DirectoryIndex never-encounterable-file-name.html
</Limit>
Does not work for me. Probably because I still want to have a directory index. If I remove my DirectoryIndex altogether WebDAV works again (no index.html or similar files exists in this directory) but of course I loose the ability to use my PHP file as directory index. I tried to specify my DirectoryIndex in a <Limit GET> but this had no effect.
Is there any way to get both DAV and DirectoryIndex to work simultaneously in Apache 2.4 on Debian (if anyhow possible without changing the source code and recompiling)?
In order to fix this, disable directory indexing for the WebDAV site.
In your sites-available/site.conf file add DirectoryIndex disabled to the <Directory> declaration, like so:
<Directory /path/to/my/webdav/dir>
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Require all granted
DirectoryIndex disabled
</Directory>
Then just reload Apache and you will no longer have that issue:
sudo service apache2 reload
For me, the following configuration solved both problems:
WebDAV works again
directory indexing, if the user uses a web browser to access the repository
It works by manually implementing the directory-indexing feature with simple rewrite rules, which are applied only for the GET request method.
The following code has to be placed inside the server config or virtual host context in the apache configuration file.
# Turn off (automatic) Directory-Indexing
DirectoryIndex disabled
RewriteEngine On
# Rewrite rules for the root directory
RewriteCond "%{REQUEST_METHOD}" "(GET)"
RewriteRule "^/$" "/index.php" [L]
# Rewrite rules for other sub-directories
RewriteCond "%{REQUEST_METHOD}" "(GET)"
# The following line checks, if the index.php file exists
RewriteCond "%{DOCUMENT_ROOT}/$1/index.php" "-f"
RewriteRule "^/(.*)/$" "/$1/index.php" [L]
Don't forget to reload Apache!
This is the solution I am currently using, located in a .htaccess file at the root of the directory tree used by the WebDav service. In this case I do not use PHP, only html files, but it can be easily adapted:
# Turn off automatic directory indexing
Options -Indexes
DirectoryIndex disabled
# Redirect directory requests to index.html, only for GET requests
RewriteEngine On
RewriteCond %{REQUEST_METHOD} "GET"
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)$ $1index.html [L]
In order to launch always the requested PHP file, just replace "index.html" on the last line by the PHP file name:
RewriteRule ^(.*)$ $1mediaManagerIndex.php [L]

Codeigniter application index.php removed randomly in url on amazon EC2 clound server

I am working on a web application. I am facing a very strange issue while navigating the app on cloud amazon EC2 instance 1 that it randomly choose some links and when I click on those links it is redirecting me to page not found or sometime home page or sometime on login page. Although session still persist.
Previously I have added the .htaccess file to removed the index.php from the urls but after noticing this issue I have revert the changes but my re_write_mode still enabled in apache httpd.conf file and .htaccess file reside on root of the application with commented code.
Apache configuration mentioned below.
DocumentRoot "/var/www/html"
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
Not sure why you would be running in that problem from what you posted...here is the .htaccess file I use at the root of all of my CI projects to remove index.php from the URL
RewriteEngine On
# Put your installation directory here:
# If your URL is www.example.com/, use /
# If your URL is www.example.com/site_folder/, use /site_folder/
RewriteBase /
# Do not enable rewriting for files or directories that exist
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# For reuests that are not actual files or directories,
# Rewrite to index.php/URL
RewriteRule ^(.*)$ index.php/$1 [PT,L]
Nothing looks extremely out of the ordinary regarding your apache config. I would say that it sounds more like a problem with your "routes." Do you have any custom routes setup in your app?
Also, did you change your $config['index_page'] and/or $config['base_url'] in your config file?