Posts Tagged ‘apache’

Fixing problems in Apache with case-sensitive URLs

Windows or Mac servers treat file names as case-insensitive, so Index.html and index.html are the same file. In Linux/Unix servers this is not the case, these files would be different. So when we create a link that does not match the case of the file name, you get an error. This is a common problem when moving files from Windows/Mac to a Linux production server and your links include incorrect case.

The ideal solution is to go over the entire site and correct these mismatches. But this may take some time and usually one finds out about the problem when the site has been moved and the domain pointed to the new server, so the problem has to be fixed ASAP.

There is a quick solution thanks to Apache’s mod_speling. If you need Apache to check different versions of a file name requested, you can use CheckCaseOnly and CheckSpelling directives. Adding one of these directives in a .htaccess file in the root directory of your site instantly fixes most of these problems. An example of this configuration is:

CheckSpelling on

We need to note that this method delivers a performance hit. Apache will have to double check each request for spelling when it does not find the file right away. So let it be noted that this is a quick fix; long term it is recommended that you backtrack and correct all the links.

24

08 2010

Setting up subdomain virtual hosts for multiple applications in a symfony project

It is very common to have multiple applications in one symfony project, like frontend, backend, api, etc. The common way to access the application is by specifying the application front controller, like

  • http://example.com/frontend.php
  • http://example.com/backend.php
  • http://example.com/api.php

Most of the time, it is nicer and better to use subdomains, like:

  • http://www.example.com/
  • http://backend.example.com/
  • http://api.example.com/

There are some hacks (here, here and here) on the net that allows you to define the application and environment based on the domain. These are good options if you need something quick and do not want to mess with the web server configuration, but you lose some flexibility and specially, all the web server log entries end up in a single file. I think it is better to have the traffic go into separate files for reporting and debugging purposes.

You can accomplish this by setting up virtual hosts for each subdomain and define the front controller for each virtual host.

1) setup the DNS entry. The recommended way is to setup a CNAME record. If you have a A record that points your domain to the IP addresss (example.com A 1.2.3.4) then you can setup a CNAME record which will point your subdomain to the same IP address without having to specify the IP in each subdomain. Then if you need to change your IP address, you just change it in one location:

example.com. A 1.2.3.4
backend.example.com. CNAME example.com.
www.example.com. CNAME example.com.
api.example.com. CNAME example.com.

You can also define a wildcard DNS like:

*.example.com. CNAME example.com.

This will make any-subdomain.example.com point to your IP address.

2) once you have your DNS records in place, it is time to configure the web server. If you use Apache, you would setup several virtual hosts like the following:

<VirtualHost *:80>
DocumentRoot /usr/local/sfproject/web
ServerName backend.example.com
ErrorLog logs/backend-error_log
CustomLog logs/backend-access_log common

<Location />
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /backend.php [L]
</IfModule>
DirectoryIndex backend.php
</Location>

</VirtualHost>

<VirtualHost *:80>
DocumentRoot /usr/local/sfproject/web
ServerName www.example.com
ServerAlias example.com
ErrorLog logs/frontend-error_log
CustomLog logs/frontend-access_log common

<Location />
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /frontend.php [L]
</IfModule>
DirectoryIndex frontend.php
</Location>

</VirtualHost>

<VirtualHost *:80>
DocumentRoot /usr/local/sfproject/web
ServerName api.example.com
ErrorLog logs/api-error_log
CustomLog logs/api-access_log common

<Location />
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /api.php [L]
</IfModule>
DirectoryIndex api.php
</Location>

</VirtualHost>

Notice that the mod_rewrite rules that usually are included in a .htaccess file are directly specified in the virtual host. If you disable .htaccess files and specify this configuration in your virtual hosts, your web server will gain some speed. If you prefer to use .htaccess files for convenience, you can have multiple .htaccess files and define which file to use in each virtual host using the directive AccessFileName.

Notice how I linked all virtual hosts to the same symfony project, and defined the default page and mod_rewrite to point to each front controller.

3) restart your web server and test.

In order to setup something like this, you will need to have full access to your environment so it is only possible to accomplish in a VPS or dedicated server. This functionality is planned for the next release of Maestro for shared hosting.

08

02 2010

Introducing the symfony web development environment installer

When Symfony 1.3 & 1.4 were released, little attention was given to a new feature that had tremendous potential: the installer. By adding –installer=installFile.php is possible to execute custom PHP code when creating a new symfony project.

So when I came across this I had an idea that could save us all some time. Every time we want to try some thing quick, do a prototype, test a plugin or simply start a new application, we create a new symfony project. The common workflow once the project is created is to add a new “virtual” hostname to the hosts file so we can reach the project through the browser, then add a virtual host to the Apache configuration, so the “virtual” hostname points to the correct web directory of the project, etc… These steps are repetitive and consume a bit of time and quite frankly I’d love to automate this whole thing. For that I created the symfony Web Development Environment Installer (also known as project codename: Swedein).

The installer will ask you a series of questions: ie. IP address, hostname, location of Apache installation. It can also locate the Apache configuration by looking for it in common places. Then it goes ahead and adds a line to the hosts file, adds the virtual host block to Apache’s configuration and restarts Apache. In a matter of seconds you should be ready to go.

swedein

To run the installer, you have a couple of options:

a) Download the installer file, rename it to SymWebDevInstaller.php and run:

symfony generate:project myproject --installer=path/to/SymWebDevInstaller.php

b) If you have support for http URLs in your PHP you can simply run:

symfony generate:project myproject --installer=http://labs.servergrove.com/SymWebDevInstaller/SymWebDevInstaller.php

Note: There is a bug in the generate:project task that prevents URLs from being used with the –installer option. This should be fixed soon.

This is being tested in:

  • Windows XP with Zend Server CE
  • Mac OS X with Zend Server CE
  • CentOS Linux
  • Ubuntu Linux

In Mac OS and Linux, the script will need to have permissions to update the hosts file and the Apache configuration. Make sure your user has permissions or use sudo to execute the installer. Restarting Apache is supported on Linux only. Other OSes coming soon.

We are looking for help to include and test in other types of installations and to add other improvements the community might think about. You can either check out the github repository where we can receive patches or send it to us and we will update it. We look forward to your feedback.

17

12 2009