Deploying a Symfony2 and Composer app on PagodaBox
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!