Symfony World blog is not maintained anymore. Check new sys.exit() programming blog.

configuring symfony application on shared hosting

Scene from "Ashes and Diamonds" by Andrzej Wajda (1958)

Notes

The following article has been tested many times on symfony version 1.4 (and has been updated few months after initial publishing).

Introduction

Sometimes a symfony project has to be deployed on shared hosting. It may be especially difficult if no SSH access is provided - this is because one of the main symfony tool is the Command Line Interface. But there are more problems, such as the directory structure of the user's account on shared hosting, which may not be changed. You are forced to modify your app structure as well then. So let's face those problems!

Alternative directory structure

The main thing is to hide the application structure (especially configuration files) from the outside. This means that all directories except for web shall not be accessible from outside. I suggest splitting the whole symfony application into 3 separate directories:

  • one for symfony core libs
  • second one for our application content
  • and the last one for the public web stuff

Example application structure would look like this:

/home/user
  /public_html
    /images
    /css
    /js
    ...
  /symfony_1_4
    /data
    /lib
    /license
    /test
    ...
  /symfony_PROJECT_NAME
    /apps
    /config
    /data
    ...

Apache document root

As you can see, the web directory has been renamed to public_html. This has been done because usually the document root apache directory is named something different than web (which is used by symfony). Now the application has to be informed of what we've just done. Modify the config/ProjectConfiguration.class.php of your application:

public function setup()
{
  ...
  $this->setWebDir($this->getRootDir().'/../public_html');
}

This part is done.

Application controllers

You'll have to modify your all controllers (all applications and all environments) to update the project configuration class path. The original web project directory has been renamed (this doesn't matter) and moved one directory up (and this matters - the path needs to be updated).

The original require_once code looks something like this:

require_once dirname(__FILE__).'/../config/ProjectConfiguration.class.php';
and should be replaced with:
require_once dirname(__FILE__).'/../symfony_PROJECT_NAME/config/ProjectConfiguration.class.php';

Symfony core lib

Now it's time to link symfony core libs to the project. There are some alternative ways to do that, one of them is to change the config/ProjectConfiguration.class.php again:

require_once dirname(__FILE__).'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';
shall be replaced with the appropriate path to the lib. But it's not the easiest way, since you'll force some difficulties with the symfony autoload mechanism. Better way is simply to create a symlink (execute from the lib/vendor directory):
ln -s ../../../symfony_1_4/ symfony
So our application is linked to the symfony lib which is inaccessible from the web, as well as the symfony application code (apps, config, lib, etc.) is inaccessible from the outside.

Alternative symfony core libs

Maybe you're curious why the symfony core lib directory is named symfony_1_4. In case you want to host many applications on one shared hosting account, there's no need to upload symfony libs into different paths (especially when their version is the same). Other applications may use this lib as well. Or you may want to host many applications on different versions of symfony, then you may have separate directories for each separate version of symfony:

/home/user
  /symfony_1_2
  /symfony_1_4 

If you want to host many symfony apps on one account, it's better to modify above structure. The best solution is to create subdomains (or any other way to access the site from a different URL) but never put everything (entire application structure) into apache's document root directory (e.g. public_html).

34 comments:

  1. 8 months after initial publishing of this article, I have updated it due to missing controllers update. The "Application controllers" section has been added and now there should be no problem at all!

    ReplyDelete
  2. Hi,
    This is very useful post.
    I think the best way to maintain a separate symfony framework files for each site.

    ReplyDelete
  3. Really helpful...

    Works nice....Thanks for sharing...

    ReplyDelete
  4. What can we do if we have just access to /html folder?
    thnx

    ReplyDelete
  5. The best thing to do then is to look for another shared hosting.

    But if you can't, I'd try to modify .htaccess. You need to redirect all traffic to the web/public_html/whatever directory, but this should not affect the URL seen in the browser.

    ReplyDelete
  6. thnx for the answer, but you see right now i cant change my shared hosting, and how can I perform this redirection? its my 1st website and im new with all these things.
    thnx

    ReplyDelete
  7. I don't have ssh access to my shared host, how do I make a symbolic link???

    ReplyDelete
  8. You can do it on your localhost machine, pack it inside an archive, put the archive on the FTP server and unpack it there (software like cPanel, DirectAdmn or so are provided with compress/uncompress feature).

    ReplyDelete
  9. symlink($target, $link) fixes that problem :)

    ReplyDelete
  10. ...or you can just export entire symfony project with all symlinks, permissions, etc. and move it to the FTP server and extract ;) some PHP functions may be forbidden on some servers due to security reasons.

    ReplyDelete
  11. Hi, this post is very helpful, but, can you put the real folders on directory structure please, you have /data repeat twice and i don't understand at all.

    Thanks great post.

    ReplyDelete
  12. It should go like this:

    /home/user - just somewhere on your hard drive
    /public_html - where the web server access
    /images
    /css
    /js
    ... - uploads, controllers, htaccess, favicon, al the rest
    /symfony_1_4 - symfony core
    /data - this data is symfony core data
    /lib
    /license
    /test
    ...
    /symfony_PROJECT_NAME - this is your project
    /apps
    /cache
    /config
    /data - this has fixtures, skeleton and sql subdirectories
    /lib
    /log
    /plugins
    /test
    /symfony* - not a directory - the command line tool

    I hope now it's clear for you :)

    ReplyDelete
    Replies
    1. Hi Tomas,

      in your scheme, folders "lib" are both in /symfony_PROJECT_NAME and /symfony_1_4 ...

      Are the same folder duplicated? o_0

      Delete
    2. Yes, you're right. But these are different lib directories. The symfony_PROJECT_NAME holds lib/model, lib/form, lib/filter (ORM-alike lib classes) and all your custom libs you'll put there. And symfony_1_4/lib is the symfony framework core lib (all symfny files). If you take download a symfony 1.x sandbox you'll see it's the same there. I haven't changed anything ;)

      cheers!

      Delete
  13. Great Job! Worked for me better than: http://www.martinsikora.com/symfony-1-4-on-shared-webhosting

    ReplyDelete
  14. Our problem is to host multiple resellers of our app. They will use the same Sym1.4, and apps, authentication etc..

    We just want to change the layout, logo and .css ?
    Thanks

    ReplyDelete
  15. U saved my day!
    Thx

    PS.: i used the makesymlink.php script from this site
    http://trac.symfony-project.org/wiki/InstallingSymfonyOnSharedHostNoSsh

    ReplyDelete
  16. @stephen Prytherch:
    It depends on how your project has been developed so far. If you want to dynamize all layout stuff (css, images), I suggest you to put all the layout stuff into CSS files only (e.g. don't put <img> tag inside layout.php - use <div class="xxx"> instead and switch CSS files). This would enable you to provide one stylesheet for each resseler. Anyway, I don't know if each reseller app requires his own separate database... so you need to provide more details on your project ;)

    Sorry that the response is so late, but google blogspot is quite buggy (I was unable to ubmit the comment)

    ReplyDelete
  17. Do we deploy the project into production locally first, and then upload the production project on shared host?

    ReplyDelete
  18. @Bagus:

    Yes, definitely you should deploy your project locally (I do it manually). If you can't do it, you may have the same problems (or even more) on production server.

    Usually the best idea is to keep your project in the repository the same way as it will be deployed on production server (e.g. renaming web into public_html and moving it one dir up in the dir tree). The way I do it (shared hosting projects) is to:
    * export subversion project
    * archive 3 distinct directories (symfony core, public_html and project dir)
    * move those archives to production server
    * unpack them there (.tar.gz can be handled by Direct Admin, cPanel, etc.)
    * manually chmod 777 for cache,log,public_html/upload directories (if there is no shell - need to click it up)
    * move public_html content (from the archive) into original public_html web server directory (on shared hosting there is always such directory jut waiting for you)
    * make sure all symlinks work fine (usualy you cannot create a symlink on a shared hosting, but you can create the locally, archive, move, unarchive and voila!)

    If you still have problem, ask further questions. Good luck!

    ReplyDelete
  19. I have no SSH. I want to install plugin. Its a shared host. How can I do so?

    ReplyDelete
    Replies
    1. You need to have a test version of your app at your local machine (or something silimar). The best way is to install the plugin on your localhost where you do have SSH and then just copy all files/clear cache/modify database on the production server. any kind of versioning software (svn, git, etc.) would be useful - e.g. you can list all files modified since a certain revision (and you know which files to copy through ftp).

      It should be really easy. You should have a local/test version of each app (need to develop an app anyhow). Allways.

      Delete
  20. Any chance this will work with symfony 1.0?

    I need to move a symfony website from a production server to the development server and moving symfony always seems to be a chore. Anyone have a good step by step tutorial? I've been searching for hours and this seems to be the best explanation so far.

    Thanks!

    ReplyDelete
    Replies
    1. Unfortunately, I don't remember sf 1.0. But I think the directory structure was the same. The whole thing is really easy and I'm pretty sure the solution is very similar to the one above - find the configuration settings which need to be changed to load LIB and WEB directories from a different location (look for sf_xxx_dir maybe?).

      Try to do it yourself with an empty sf 1.0 project.

      Delete
  21. I have another question any ideas on how to put on a shared server with only ftp access an application made ​​with Symfony 2.io I made ​​a blog but now I'm stuck because I can not put it on the server thanks in advance for the help

    ReplyDelete
    Replies
    1. I haven't deployed sf2 on shared hosting yet, but looking at symfony2's standard edition front controller, app.php:

      require_once __DIR__.'/../app/bootstrap.php.cache';
      require_once __DIR__.'/../app/AppKernel.php';

      it seems that it goes just one dir up (from the virtual host document root) and search for app directory. So I guess renaming 'web' to anything else should do the job, and if not - check server logs.

      Having FTP access only doesn't change anything comparing to article above. Shared hosting assumes that you don't have SSH - you just use FTP to move files (+ pack/unpack) and change permissions for log/cache/uploads directories.

      Delete
  22. I had a project hosted on my local machine then migrated it to remote server, same settings, I've even managed to make sure all the mods enabled are the same as well as all the php libraries installed. However when I target the home page I get the info minus the missing styles (i.e images and javascripts.
    Anything I am missing? I'm on symfony 1.4.

    ReplyDelete
    Replies
    1. It seems that you have set wrong filepaths to your assets (css, js, images and so on) in the view layer (templates). Check what are the paths to your assets on your localhost and compare them with corresponding paths on the production server. You may also try to display each of your assets (http://mydomain.com/img/bg.jpg or something like that) - then check apache server logs - and try to conclude what resource the server fails to retrieve. Good luck :)

      Delete
  23. Hi! Can you recommand me a good webhostin for symfony2?Thanks

    ReplyDelete
    Replies
    1. Any php 5.3+ with shell access should be ok.
      I've been using a small Polish company hosting, so I cannot recommend anything global.

      Delete
  24. Does this tutorial also apply to symfony2?

    ReplyDelete
  25. You have done good job.

    ReplyDelete
    Replies
    1. Thank you :). This post seems to be the most popular on this blog (after 5 years have passed).

      Delete