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
Tweet

More Decks by Jonathan Reinink

Other Decks in Technology

Transcript

  1. View Slide

  2. Jonathan Reinink
    Canadian web developer.

    View Slide

  3. View Slide

  4. View Slide

  5. Plates
    A native PHP template system.

    View Slide

  6. Glide
    On-demand image manipulation library

    View Slide

  7. Deployments
    Moving your apps from dev to production.

    View Slide

  8. Average Projects
    What do they look like?

    View Slide

  9. Deployment
    Mistakes

    View Slide

  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

    View Slide

  11. Edit files in nano on the server.
    Continuous deployment achieved.
    —Jeff Carouth


    View Slide

  12. Life is too short to deploy
    manually over FTP
    —Joel Clermont


    View Slide

  13. Automation

    View Slide

  14. (continuous)
    Deployments

    View Slide

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

    View Slide

  16. Less Errors
    Computers are better at repetitive tasks.

    View Slide

  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?

    View Slide

  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.

    View Slide

  19. Bonus Tasks
    Run tests to verify that they pass.
    Check coding standards.
    Automated code analysis.

    View Slide

  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.

    View Slide

  21. Approaches
    PaaS Products
    Deployment Services
    CI Services
    Task Runners

    View Slide

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

    View Slide

  23. View Slide

  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

    View Slide

  25. {
    "require": {
    "php": "~5.6.0",
    "ext-gd": "*",
    },
    "scripts": {
    "post-install-cmd": [
    "php artisan clear-compiled",
    "php artisan optimize"
    ],
    "compile": [
    "php artisan migrate --force"
    ]
    }
    }

    View Slide

  26. Pushing to [email protected]:myrepo.git
    Warning: Permanently added 'heroku.com,50.19.85.156' (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

    View Slide

  27. View Slide

  28. View Slide

  29. View Slide

  30. # 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

    View Slide

  31. composer:
    method: install
    mode: always
    !
    post-deploy:
    script: artisan
    args:
    - migrate
    fortrabbit.yml

    View Slide

  32. View Slide

  33. View Slide

  34. View Slide

  35. View Slide

  36. View Slide

  37. View Slide

  38. Deployment
    Services
    Less management for a small cost.

    View Slide

  39. View Slide

  40. View Slide

  41. View Slide

  42. View Slide

  43. View Slide

  44. View Slide

  45. View Slide

  46. View Slide

  47. View Slide

  48. View Slide

  49. View Slide

  50. View Slide

  51. View Slide

  52. View Slide

  53. Continuous
    Integration
    Services

    View Slide

  54. View Slide

  55. View Slide

  56. View Slide

  57. View Slide

  58. View Slide

  59. View Slide

  60. View Slide

  61. View Slide

  62. Task
    Runners
    Remote server automation.

    View Slide

  63. View Slide

  64. Robo

    View Slide

  65. View Slide

  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

    View Slide

  67. /.rocketeer
    config.php
    hooks.php
    paths.php
    remote.php
    scm.php
    stages.php
    strategies.php

    View Slide

  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

    View Slide

  69. // The root directory where
    // your applications will be deployed
    'root_directory' => ‘/var/www/mynewapp/',
    remote.php

    View Slide

  70. // Tasks to execute after the
    // core Rocketeer Tasks
    'after' => [
    'deploy' => [
    'sudo service php-fpm reload',
    'php artisan migrate --force',
    ],
    ],
    hooks.php

    View Slide

  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:passwo[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

    View Slide

  72. That’s all folks!
    Give continuous deployment a try!

    View Slide

  73. Thanks!
    Follow me on Twitter at @reinink.
    Rate this talk https://joind.in/13068.

    View Slide