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. 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
  2. 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?
  3. 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.
  4. Bonus Tasks Run tests to verify that they pass. Check

    coding standards. Automated code analysis.
  5. 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.
  6. # 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
  7. { "require": { "php": "~5.6.0", "ext-gd": "*", }, "scripts": {

    "post-install-cmd": [ "php artisan clear-compiled", "php artisan optimize" ], "compile": [ "php artisan migrate --force" ] } }
  8. Pushing to [email protected]: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
  9. # Add your Fortrabbit remote address to Git git remote

    add fortrabbit [email protected]... ! # Make a commit git commit -am 'Made a change! [trigger:composer]' ! # Push your code to master git push fortrabbit master
  10. 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
  11. // 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
  12. // The root directory where // your applications will be

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

    'after' => [ 'deploy' => [ 'sudo service php-fpm reload', 'php artisan migrate --force', ], ], hooks.php
  14. # 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:[email protected]/reinink/rocketeer.git" "/srv/users/rocketeer/ap [[email protected]] (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 [[email protected]] (production) Loading composer repositories with package informatio [[email protected]] (production) Installing dependencies from lock file