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.