I manage a few Symfony 2/3 projects on my Jenkins server that I am deploying to a live server. This is my current setup:
composer install
(prod mode, optimize autoloader)bower install
to fetch my assetsgulp
build, that minifies and concatenates css / javascript (We don't use assetic)After the build, I archive the artifacts of the build without the vendor
, node_modules
and bower_components
folders as a zip file using the "Compress Artifacts" Plugin.
I use the "Promoted builds" plugin and the "Publish over SSH" plugin in combination: If I want to "go live" with a build, I publish the artifacts (my zip file) over SSH to my live system in a directory called staging_dir
. After the file upload, I execute some SSH commands:
staging_dir
composer install
on the live system (same config as during the build)bower install
and the gulp
build is not necessary, as we use the assets we created during the build)backup
folderstaging_dir
I would now like to collect some best practices for deployment:
vendor
folder to the live system instead of executing composer install
there again?bower install
and gulp
build on the live system again or do you use the published assets?Me and a couple of colleagues have been dealing with this for quite a while now. When we started it was quite hard to find good posts regarding this topic. This is why I'd like to share what we've found to be working "best" for us.
One of our clients has a big and heavy platform used for managing his business process (something like an ERP & CRM). The platform has been initially developed using Symfony 2 and we've now upgraded to Symfony 3. To be sure everything is working properly the project has tons of test cases. We also use:
Once somebody commits to our git server, a hook lets Jenkins know and a build is triggered. Once the job finishes successfully we manually trigger the deployment. This is done by logging into the client's machine(s) and triggering a script we've developed.
We used to approach this the same way as you - upload the archive after jenkins finishes the job. This, however, proved to be quite problematic because in some cases the archive might get broken (i.e. due to network connection issues between the jenkins instance and the production server). Also it took considerably longer to upload a file from our server to the client's server. This is why we decided to use git and pull the necessary version from there. Using git proved to be more reliable and ensures you have an absolute copy of the project on the client's side. Also, rolling back to previous version is just one git checkout
away :)
Because most of us already had experience with ant
and php
we have decided to use Phing and create a build script and automate most of the regular tasks. In the build script we've added most of the common tasks we run all the time such as install, upgrade, clear cache, install assets, etc. Then we made this script available on each production server.
Once the jenkins build job is successful and we've manually released & tagged the version of the product, we'd run phing update
on the client's machine via SSH (this step could have been automated but was intentionally not due to some project requirements). What this command would do is:
19a6d9
) proceeds to next stepphing maintenance:on
(sets the platform in an offline mode)git fetch origin 19a6d9
git checkout 19a6d9
phing composer:install
phing database:upgrade
(which runs a couple of commands, including database backup and doctrine:migrations:migrate
)phing assets
(runs bower install
, assetic
commands and compiles all js/css into one.css
and one.js
)phing cache:clean
phing maintenance:off
(turns the platform on)Our phing update
task is also surrounded by trycatch
and in case the update phase hits a brick it would automatically go into the rollback phase. It is done via a phing rollback PREVIOUS_VERSION
command which does:
git checkout PREVIOUS_VERSION
- restores the fs to the previous git versionphing composer:install
phing database:rollback PREVIOUS_VERSION
phing assets
phing report
(this reports there's an issue with the upgrade to our issue tracker with a log file attached)Do you prefer to transfer the bower_components
and the vendor
folder to the live system instead of executing bower install
and composer install
there again?
bower install
and composer install
, because after the first time you'll already have everything cached. Every next run would be almost instantaneous or at least much faster than re-uploading all assets again and again via ftp. That might save you somewhat bandwidth and most importantly time. If you choose to do a similar setup to mine, you might want to avoid compiling
the js/css on the Jenkins instance as you'll be doing that on the prod server.How do you handle your passwords when executing a live promotion?
The setup mainly depends on your project requirements, the resources you have available (i.e. vps, shared hosting, git, ssh, etc) and your release process. As you can see, our deployment is slightly different from what you're doing. This doesn't make it bad nor good - it just suits our needs. If what you already have works for you and solves all of your problems - you should stick with it and try to optimize it. In case you're just getting started this is what you should be most careful about:
FULL... BACKUPS! Having a backup of the production filesystem is great, but you should also have a backup of the database. During the development course of your project it's likely you'd have new features which change the database. Some of those changes may be backwards incompatible. So be sure to backup everything or you might end up having a fs backup without a db to work with thus not being able to rollback.
Rollback - create a script which does all necessary steps to rollback the project to the previous version. If you're under a lot of pressure or things are time sensitive you might unintentionally make a mistake and break the backup or something else... Therefore make a script which does this for you.
Test the deployment process locally or on a testing machine to be sure everything really works before doing it on the actual production server.
I hope this helps you find the best solution to your release & deployment process. If you happen to find a better solution, please post it as an answer - it will definitely be helpful!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With