• Deploying a Symfony2 and Composer app on PagodaBox

    by  • April 16, 2012 • DevOps, PaaS, PHP • 0 Comments

    I have been working on a little pet project and wanted to put it up somewhere to show to a few people how it was going. I wanted something really simple so I decided to give the PHP PaaS solutions a try. Its a very simple Symfony 2.1 based app using Composer for vendor management, so I went on a quest to see what could be done and how.

    I have always liked Orchestra, especially because I know the whole crew, but I was left stranded on how I could run the composer commands I needed after deploy. The feature was not done yet, so I moved onto Pagoda Box, thinking I was going to hit the same wall. I was pleasantly surprised that there was a solution and decided to give it a try.

    It was mostly painless, but a few quirks kept me up late chatting with their excellent and very friendly support staff. So I decided to write up a few line about it.

    Boxfile

    The Boxfile defines all the config for your app and that’s where the magic happens. This is basically the extent of changes you need to make to your application.

    Basic configuration

    Some of the configuration is straight forward, so let’s get them out of the way. Be sure to adjust between app and app_dev accordingly.

        web1:
            name: mysf2site
            document_root: web
            default_gateway: app.php
            index_list: [app.php]
            php_version: 5.3.8
    

    Writable directories

    As soon as you deploy a Symfony app you remember that you need to make the cache and logs folders writable or you will get a very nice blowup in your face. Pagoda let’s you do this but there is a couple thing you should know.

    The writable directories configuration is meant for directories your “Web” role will write into. This means uploads, caching and related events, its does not relate to build steps. During the “build” step of your application (this is when you run Composer), everything is writable, so you don’t need to make your vendor folder writable for example.

    Writable folders are emptied after initial deploy. This means if you decide to make your app folder writable because you have the crazy idea that it will be needed for bootstrap.php.cache, your deploy will give you a nice big empty app directory. So remember to only use this config for the folders that need it. Update: The nice folks at Pagoda explained to me that the “empty folder” effect is only after initial deploy, subsequent deploys don’t empty the directories for obvious reasons (i.e. you can use this for uploads).

    This is what it should look like:

    shared\_writable\_dirs:
      - app/cache
      - app/logs
    

    Extensions

    So it might be a good idea to make sure all the extensions are there, this is very easy, and this is the list i came up with:

        php_extensions:
            - intl
            - mbstring
            - xsl
            - apc
            - mysql
            - pdo_mysql
            - zip
    

    Notice zip, this is very important as Composer depends on this extension or falls back onto unzip, which is not a valid executable in a Pagoda server. The rest is standard Symfony stuff and personal choices.

    The Configuration and Database

    Personally I like to keep my parameters.yml file out of my repositories, to this was a challenge here, how do I create or copy in this configuration or how do i keep my config out of there.

    Getting values into the system was a very nice suggestion on the Pagoda Help site. Using ENV variables you can inject this straight into the Symfony2 parameters.yml file, so i setup my database stuff for now with: SYMFONY__DATABASE__NAME which becomes %database.name% in the yml file. Rinse and repeat for all DB variables and create these in the Dashboard with the proper values.

    But I still needed to write the parameters.yml file to the system, and that’s where afer_build comes in. I needed to write multiple lines, so i cheated and went for a few echo calls.

    Update: It appears you do not even need to have a parameters.yml file, you can go straight from ENV to Symfony as @igorwesome pointed out to me and this article

    </pre>
    after_build:
     - "echo 'parameters:' >> app/config/parameters.yml"
     - "echo ' database_driver: pdo_mysql' >> app/config/parameters.yml"
     - "echo ' database_host: %database.host%' >> app/config/parameters.yml"
     - "echo ' database_port: 3306' >> app/config/parameters.yml"
     - "echo ' database_name: %database.name%' >> app/config/parameters.yml"
     - "echo ' database_user: %database.user%' >> app/config/parameters.yml"
     - "echo ' database_password: %database.password%' >> app/config/parameters.yml"
     - "echo ' mailer_transport: smtp' >> app/config/parameters.yml"
     - "echo ' mailer_host: localhost' >> app/config/parameters.yml"
     - "echo ' mailer_user: ~' >> app/config/parameters.yml"
     - "echo ' mailer_password: ~' >> app/config/parameters.yml"
     - "echo ' locale: en' >> app/config/parameters.yml"
     - "echo ' secret: [secret]' >> app/config/parameters.yml"
     - "php bin/composer.phar install"
    <pre>

    This is also where you call Composer and let it do its thing on your vendors. I had also added my doctrine call here to generate and update my DB schema, but that proved to be a failure.

    The Database is not available during the after_build step. Looking back this is kind of obvious as stuff only goes live after its built and ready. Luckily they also offer the before_deploy step, so this is where you want your doctrine calls to go.

        before_deploy:
            - "php app/console doctrine:schema:update --force"
    

    Conclusion

    After playing around with those settings and learning the quirks about the steps and the writable directories it was smooth sailing and the app came up nice and clean as expected.

    I must say that the Pagoda Box Support crew was really nice during my trials and errors and really helped me get over the problems. Hopefully this will give you a little heads up if you attempt the same thing. Enjoy!

    About

    Rafael Dohms is an experienced PHP Developer, Evangelist, Speaker and Contributor. During his years of experience he has become an active member of the community and founded 3 User Groups. He moved to the Netherlands to integrate the WEBclusive team and share his passion for code quality and innovation in the Crowd funding world. In his spare time he also helps manage the AmsterdamPHP User Group, amongst other projects.

    http://doh.ms

    0 Responses to Deploying a Symfony2 and Composer app on PagodaBox

    1. Igor Wiedler
      April 16, 2012 at 14:31

      You can skip the crazy parameters generation stuff, as symfony supports resolving env vars to parameters directly: http://symfony.com/doc/current/cookbook/configura

      • Rafael Dohms
        April 16, 2012 at 14:55

        That's awesome, updated the article with a note and will fix it when i get a chance.

    2. April 17, 2012 at 13:48

      Just for the record, you could also have used the multi-line YAML syntax instead of the 30 echos: http://pastie.org/3803858

      • Rafael Dohms
        April 17, 2012 at 15:31

        Yes that is mostly my fault because of my lack of bash-fu :D

    3. April 25, 2012 at 15:49

      Thanks for that article, really helpful! However I have one question: where do you store sessions, with memcached ?

    4. Heiko
      May 11, 2012 at 12:44

      When i am runnig the after_build hook with "php composer.phar install" i always get a "line 1: 124 Segmentation fault" – any ideas?

    5. mal
      July 8, 2012 at 1:36

      just another deployment method for symfony2 -> http://capifony.org/

    6. Rafael Dohms
      April 16, 2012 at 16:34

      Joseph, that's interesting, i just found that in my tests when I made the "app" folder writable, all content in it was ereased after the build. It might have been a race condition in that case i guess.

    7. Rafael Dohms
      April 16, 2012 at 19:35

      That makes sense, will add a note.

    Leave a Reply