I'm developing a website local and just switched from Windows to Ubuntu 16.04 - Sadly my .htaccess doesn't seems to work since rewrite rules don't apply and sources can't be found.

I activated:

sudo a2enmod rewrite  

rewrite_rule (shared) is listed via:

sudo apache2ctl -M

My website files (including my .htaccess) are located under


My .htaccess

Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /

# Hide Index
IndexIgnore *

# Forbid accessing certain sites
RedirectMatch 403 ^/.gitignore$
RedirectMatch 403 ^/.htaccess$
RewriteRule ^(?!index)(?!.*functions).*\.(php|rb|py|txt|md|sql|inc)$ - [F,L,NC]

# Remove 'php' folder in URL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\w-]+)/$ php/$1.php [L] 

# Hide .php file ending in URL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]

# Alter "php" in url to "site"
#RewriteRule ^site/(.*) php/$1

# Manage Access-Control-Allow-Origin
#Access-Control-Allow-Origin "https://blockchain.info"

# Enabling GZIP Compression
<ifModule mod_gzip.c>
    mod_gzip_on Yes
    mod_gzip_dechunk Yes
    mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
    mod_gzip_item_include handler ^cgi-script$
    mod_gzip_item_include mime ^text/.*
    mod_gzip_item_include mime ^application/x-javascript.*
    mod_gzip_item_exclude mime ^image/.*
    mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*

My /etc/apache2/apache2.conf

# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
Mutex file:${APACHE_LOCK_DIR} default

# PidFile: The file in which the server should record its process
# identification number when it starts.
# This needs to be set in /etc/apache2/envvars

# Timeout: The number of seconds before receives and sends time out.
Timeout 300

# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
KeepAlive On

# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
MaxKeepAliveRequests 100

# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
KeepAliveTimeout 5

# These need to be set in /etc/apache2/envvars

# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
HostnameLookups Off

# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here.  If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
ErrorLog ${APACHE_LOG_DIR}/error.log

# LogLevel: Control the severity of messages logged to the error_log.
# Available values: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the log level for particular modules, e.g.
# "LogLevel info ssl:warn"
LogLevel warn

# Include module configuration:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf

# Include list of ports to listen on
Include ports.conf

# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied

<Directory /usr/share>
    AllowOverride None
    Require all granted

<Directory /var/www>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted

# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives.  See also the AllowOverride
# directive.
AccessFileName .htaccess

# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
<FilesMatch "^\.ht">
    Require all denied

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

# Include of directories ignores editors' and dpkg's backup files,
# see README.Debian for details.

# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf

# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf

# Include phpmyadmin
Include /etc/phpmyadmin/apache.conf

My etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com

ServerAdmin webmaster@localhost
DocumentRoot /var/www/html

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf

AccessFileName .htaccess

<Directory "/var/www">
  AllowOverride All
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

I also applied rights via

sudo chmod -R 777 /var/www/html

and restarted apache via

sudo service apache2 reload
sudo service apache2 restart

but also restarted the computer at some point.

After all this .htaccess still won't get loaded, so what have I forgotten?

  • 1
    Can you confirm whether it's really .htaccess or just mod_rewrite that isn't working? Which version of Apache? – MrWhite Mar 19 '17 at 10:09
  • AllowOverride All should be what makes htaccess work. I would try matching the directory containing that to the document root: <Directory "/var/www/html"> – Stephen Ostermiller Mar 19 '17 at 10:12
  • 1
    BTW- You should change Indexes to -Indexes for security reasons. If you chose to use -Indexes, you likely will have to change FollowSymLinks to +FollowSymLinks or Apache will fail to start. – closetnoc Mar 19 '17 at 17:03
  • 1
    Consider that when Apache starts up, it applies directives in the order found. This would be apache2.conf => 000-default.conf => .htaccess. Configuration files require restarting Apache. Some directives require restarting Apache. Your .htaccess file should only contain those directives that do not require a restart and you may need to change without a restart. Typically, these are things such as redirects. – closetnoc Mar 19 '17 at 17:57
  • 1
    Enable LogLevel debug in apache2.conf, restart apache, and check your error logs after loading a page again. – nathangiesbrecht Jun 28 '17 at 17:43

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.