Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Practical deployments for average projects

Practical deployments for average projects

It makes a lot of sense to have a fully automated continuous integration system for your large SaaS product. But what about your average web project? Does this sort of infrastructure make sense for your company website or even your friend's blog? After all, FTP works fine, right? Well you might be surprised to learn how many awesome tools are available for even the smallest projects. In this talk I'll outline some practical approaches to automating your “average project” deployments. This includes how to actually copy your files to your deployment server, run your tests, install Composer dependencies, complete database migrations and more.

Jonathan Reinink

March 14, 2015

More Decks by Jonathan Reinink

Other Decks in Technology


  1. None
  2. Jonathan Reinink Canadian web developer.

  3. None
  4. None
  5. Plates A native PHP template system.

  6. Glide On-demand image manipulation library

  7. Deployments Moving your apps from dev to production.

  8. Average Projects What do they look like?

  9. Deployment Mistakes

  10. Developed directly on the production server Manually uploaded files over

    FTP I’ve included my vendor directory in my repo Migrated my DB directly from PhpMyAdmin SSH’d into production server to do a `git pull` or `composer install` I didn’t deploy as often as I should Other team members couldn’t deploy
  11. Edit files in nano on the server. Continuous deployment achieved.

    —Jeff Carouth “ ”
  12. Life is too short to deploy manually over FTP —Joel

    Clermont “ ”
  13. Automation

  14. (continuous) Deployments

  15. Increased Productivity Allowed me to focus on my work.

  16. Less Errors Computers are better at repetitive tasks.

  17. Why not? I'm a programmer. That stuff for DevOps. Tools

    like Jenkins and Capistrano look way too confusing. My projects are too small to bother. The tooling is too expensive. I’m only one dev, is it really worth the effort?
  18. Key Tasks We need to move some code. We need

    to install our dependencies. We need to migrate our database. We need to compile/minify assets. We need to flush our cache/run optimizations.
  19. Bonus Tasks Run tests to verify that they pass. Check

    coding standards. Automated code analysis.
  20. Wish List More than one developer can deploy. Configuration must

    be minimal. All configuration online in one place. It has to be affordable. Deployment should happen automatically.
  21. Approaches PaaS Products Deployment Services CI Services Task Runners

  22. PaaS Products Hosting with built-in deployment tools.

  23. None
  24. # You need a composer.json file echo "{}" > composer.json

    ! # Create a new Heroku app heroku create mynewapp ! # Any you domains heroku domains:add mynewapp.com heroku domains:add www.mynewapp.com ! # Push your code to master git push heroku master
  25. { "require": { "php": "~5.6.0", "ext-gd": "*", }, "scripts": {

    "post-install-cmd": [ "php artisan clear-compiled", "php artisan optimize" ], "compile": [ "php artisan migrate --force" ] } }
  26. Pushing to git@heroku.com:myrepo.git Warning: Permanently added 'heroku.com,' (RSA) to t

    Fetching repository, done. -----> Fetching custom git buildpack... done -----> PHP app detected -----> No runtime required in composer.json, defaulting to PHP -----> Installing system packages... - PHP 5.6.6 - Apache 2.4.10 - Nginx 1.6.0 -----> Installing PHP extensions... - exif (composer.lock; bundled) - gd (composer.lock; bundled) - mbstring (composer.lock; bundled) - zend-opcache (automatic; bundled) -----> Installing dependencies... Composer version 1.0-dev (833ce984264204e7d6576ab082660105c7d8f Loading composer repositories with package information Installing dependencies from lock file
  27. None
  28. None
  29. None
  30. # Add your Fortrabbit remote address to Git git remote

    add fortrabbit git@frbit.com... ! # Make a commit git commit -am 'Made a change! [trigger:composer]' ! # Push your code to master git push fortrabbit master
  31. composer: method: install mode: always ! post-deploy: script: artisan args:

    - migrate fortrabbit.yml
  32. None
  33. None
  34. None
  35. None
  36. None
  37. None
  38. Deployment Services Less management for a small cost.

  39. None
  40. None
  41. None
  42. None
  43. None
  44. None
  45. None
  46. None
  47. None
  48. None
  49. None
  50. None
  51. None
  52. None
  53. Continuous Integration Services

  54. None
  55. None
  56. None
  57. None
  58. None
  59. None
  60. None
  61. None
  62. Task Runners Remote server automation.

  63. None
  64. Robo

  65. None
  66. No connections have been set, please create one: (production)production No

    host is set for [production/0], please provide one:mynewapp.com No username is set for [production/0], please provide one:jonathan No password or SSH key is set for [production/0],[key/password]password No password is set for [production/0], please provide one: production/0 | Ignite (Creates Rocketeer's configuration) What is your application's name ? (rocketeer)mynewapp The Rocketeer configuration was created at rocketeer/.rocketeer # Install with Composer composer require --dev anahkiasen/rocketeer ! # Run configuration setup php vendor/bin/rocketeer ignite
  67. /.rocketeer config.php hooks.php paths.php remote.php scm.php stages.php strategies.php

  68. // The SCM used (supported: "git", "svn") 'scm' => 'git',

    ! // The address to your repository 'repository' => ‘https://jonathan@bitbucket...', ! // The repository credentials 'username' => '', 'password' => '', ! // The branch to deploy 'branch' => 'master', scm.php
  69. // The root directory where // your applications will be

    deployed 'root_directory' => ‘/var/www/mynewapp/', remote.php
  70. // Tasks to execute after the // core Rocketeer Tasks

    'after' => [ 'deploy' => [ 'sudo service php-fpm reload', 'php artisan migrate --force', ], ], hooks.php
  71. # Run the deployment php vendor/bin/rocketeer deploy No password or

    SSH key is set for [production/0], [key/password]password No password is set for [production/0], please provide one: No username is set for [repository], please provide one:jonathan No password is set for [repository], please provide one: | Deploy (Deploys the website) |-- Primer (Run local checks to ensure deploy can proceed) |-- CreateRelease (Creates a new release on the server) |---- Deploy/Clone (Clones a fresh instance of the repository by SCM) |===> Cloning repository in "/srv/users/rocketeer/apps/rocketeer/releases/20150312135546" $ git clone "https://reinink:password@bitbucket.org/reinink/rocketeer.git" "/srv/users/rocketeer/ap [rocketeer@rocketeer.reinink.ca] (production) Cloning into '/srv/users/rocketeer/apps/rocketeer/rel |===> Initializing submodules if any $ cd /srv/users/rocketeer/apps/rocketeer/releases/20150312135546 $ git submodule update --init --recursive |-- Dependencies (Installs or update the dependencies on server) |---- Dependencies/Polyglot (Runs all of the above package managers if necessary) |------ Dependencies/Composer (Installs dependencies with Composer) $ cd /srv/users/rocketeer/apps/rocketeer/releases/20150312135546 $ /usr/bin/composer5.6-sp install --no-interaction --no-dev --prefer-dist [rocketeer@rocketeer.reinink.ca] (production) Loading composer repositories with package informatio [rocketeer@rocketeer.reinink.ca] (production) Installing dependencies from lock file
  72. That’s all folks! Give continuous deployment a try!

  73. Thanks! Follow me on Twitter at @reinink. Rate this talk