A typical setup for our Symfony 2 projects lately has been to split up the application Kernel into separate parts.

In practice usually it boils down to this:

  • AdminKernel.php : Integrates and uses a large part of Sonata Admin and the entire Doctrine stack
  • ApiKernel.php : Only bootstraps the bare minimum to serve API requests, so no Twig, Sonata is loaded here
  • MediaKernel.php : Takes care of scaling and serving resized images. Internally Glide is used for this

On JoliCode.com a pretty blog post was published about how you could organize this yourself in your own project: http://jolicode.com/blog/multiple-applications-with-symfony2

Our (simplified) directory structure currently looks something like this:

├── apps
│   ├── admin
│   │   └── AdminKernel.php
│   ├── api
│   │   └── ApiKernel.php
│   └── media
│       └── MediaKernel.php
└── web    ├── admin
    │   ├── app_dev.php
    │   └── app.php
    ├── api
    │   ├── app_dev.php
    │   └── app.php
    └── media
        ├── app_dev.php
        └── app.php

In Nginx configuration you might want to use a configuration file like below:

server {
    listen   80;
    server_name example.com;
    root /var/www/example/;

    # This is where our frontend JS app is running
    location / {
        alias /var/www/example/frontend/build/;
        try_files $uri /build/app.php;
    location /admin/ {
        alias /var/www/example/backend/web/admin/;
        try_files $uri /backend/web/admin/app.php;

    location /api/ {
        rewrite ^ /backend/web/api/app.php;

    location /media/ {
        alias /var/www/example/backend/web/media/;
        try_files $uri /backend/web/media/app.php;
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;

In the configuration above you will notice that try_files is not used for the /api location. This is because we will never serve static files from the hard drive on this path. All requests will be handled by PHP.