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

A beginner’s guide to deployments - PHPTour

A beginner’s guide to deployments - PHPTour

Deploying an application means different things to different people. It may be as simple as running git pull on a server, or as complex as building RPMs and deploying to a canary set of servers. This talk covers both ends of the spectrum and the points in between. We’ll outline several tried and tested deployment methodologies that everyone can use, whether you’re working with a simple WordPress site or a dozen micro-services.

Michael Heap

May 18, 2017
Tweet

More Decks by Michael Heap

Other Decks in Technology

Transcript

  1. @mheap at #phptour
    A beginners guide
    to deployments

    View Slide

  2. @mheap
    Let’s talk deployment

    View Slide

  3. @mheap
    Your deploys should be as boring,
    straightforward, and stress-free as
    possible.
    - Zach Holman
    (https://zachholman.com/posts/deploying-software)

    View Slide

  4. @mheap
    Deployment for beginners

    View Slide

  5. @mheap
    1. What is a deployment?
    2. Option A: External tools
    3. Option B: Internal tools
    4. Option C: System packages
    5. Option D: Blue / Green deployments
    6. Option E: Immutable infrastructure
    7. Deployment techniques
    8. Summary

    View Slide

  6. @mheap
    What is a deployment?

    View Slide

  7. @mheap
    Code

    View Slide

  8. @mheap
    Dependencies

    View Slide

  9. @mheap
    Configuration

    View Slide

  10. @mheap
    Database Migrations

    View Slide

  11. @mheap
    Other Migrations

    View Slide

  12. @mheap
    Assets

    View Slide

  13. @mheap
    Post Install Tasks

    View Slide

  14. @mheap
    We’re aiming for…

    View Slide

  15. @mheap
    Your deploys should be as boring,
    straightforward, and stress-free as
    possible.
    - Zach Holman
    (https://zachholman.com/posts/deploying-software)

    View Slide

  16. @mheap
    Our Codebase

    View Slide

  17. @mheap
    Simple to do list application

    View Slide

  18. @mheap
    Composer
    Silex
    Doctrine Migrations

    View Slide

  19. @mheap
    Time to deploy!

    View Slide

  20. @mheap
    Option A: External tool

    View Slide

  21. @mheap
    @mheap

    View Slide

  22. @mheap
    @mheap

    View Slide

  23. @mheap
    @mheap

    View Slide

  24. @mheap
    @mheap

    View Slide

  25. @mheap
    @mheap

    View Slide

  26. @mheap
    @mheap

    View Slide

  27. @mheap
    @mheap

    View Slide

  28. @mheap
    @mheap

    View Slide

  29. @mheap
    @mheap

    View Slide

  30. @mheap
    @mheap

    View Slide

  31. @mheap
    Useful tools
    Beanstalkapp
    DeployHQ
    Laravel Forge

    View Slide

  32. @mheap
    1. Easy setup
    2. One-click deployments
    3. Environment support
    4. Can only deploy from repo
    1. Files copied one by one
    2. Composer run on server
    3. No build steps
    4. Their way, or the highway
    5. Can’t deploy if provider is
    offline
    Pros Cons

    View Slide

  33. @mheap
    Option B: Internal tool

    View Slide

  34. @mheap
    @mheap

    View Slide

  35. @mheap
    $ gem install capistrano

    View Slide

  36. @mheap
    $ cap install
    => mkdir -p config/deploy
    => create config/deploy.rb
    => create config/deploy/staging.rb
    => create config/deploy/production.rb
    => mkdir -p lib/capistrano/tasks
    => create Capfile
    => Capified

    View Slide

  37. @mheap
    $ cat config/deploy.rb
    lock '3.6.1'
    set :application, 'silex_todo'
    set :repo_url, '[email protected]:mheap/fake-todo-app.git'
    set :deploy_to, '/var/www/todo'

    View Slide

  38. @mheap
    $ cat config/deploy/production.rb
    server 'todo.example.com', user: 'deploy', roles: %w{app db}

    View Slide

  39. @mheap
    $ cap production deploy
    00:00 git:wrapper
    01 mkdir -p /tmp
    02 chmod 700 /tmp/git-ssh-silex_todo-production-michael.sh
    00:07 git:check
    01 git ls-remote --heads [email protected]:mheap/silex-todo-demo.git
    00:08 deploy:check:directories
    01 mkdir -p /var/www/todo/shared /var/www/todo/releases
    00:08 git:clone
    01 git clone --mirror [email protected]:mheap/silex-todo-demo.git /var/www/todo/repo
    01 Cloning into bare repository '/var/www/todo/repo'...
    00:10 git:update
    01 git remote update --prune
    01 Fetching origin
    00:11 git:create_release
    01 mkdir -p /var/www/todo/releases/20161106090926
    02 git archive master | tar -x -f - -C /var/www/todo/releases/20161106090926
    00:12 git:set_current_revision
    01 echo "6cc1b6cbc827e205b24d0d599ea7b667a3ec5ca0" >> REVISION
    00:12 deploy:symlink:release
    01 ln -s /var/www/todo/releases/20161106090926 /var/www/todo/releases/current
    02 mv /var/www/todo/releases/current /var/www/todo
    00:12 deploy:log_revision
    01 echo "Branch master (at 6cc1b6cbc827e205b24d0d599ea7b667a3ec5ca0) deployed as
    release 20161106090926 by michael" >> /var/www/todo/revisions.log

    View Slide

  40. @mheap
    $ cap production deploy
    Generate and upload deployment script
    Clone repo
    Generate archive from repo
    Untar archive into releases folder
    Symlink current folder to the latest release

    View Slide

  41. @mheap
    $ gem install capistrano-composer
    In Capfile:
    require 'capistrano/composer'

    View Slide

  42. @mheap
    $ cap production deploy
    00:18 composer:run
    01 composer install --no-dev --prefer-dist --no-interaction --
    quiet --optimize-autoloader
    ✔ 01 [email protected] 1.023s

    View Slide

  43. @mheap
    lib/capistrano/tasks/database_tasks.rake:
    namespace :database do
    desc 'migrate database'
    task :migrate do
    on roles(:db) do
    execute "cd #{release_path} && ./vendor/bin/
    doctrine-migrations migrations:migrate --db-configuration
    config/db-config.php --configuration config/migrations.yml"
    end
    end
    end

    View Slide

  44. @mheap
    lib/capistrano/tasks/database_tasks.rake:
    namespace :database do
    desc 'migrate database'
    task :migrate do
    on roles(:db) do
    execute "cd #{release_path} && ./vendor/bin/
    doctrine-migrations migrations:migrate --db-configuration
    config/db-config.php --configuration config/migrations.yml"
    end
    end
    end

    View Slide

  45. @mheap
    lib/capistrano/tasks/database_tasks.rake:
    namespace :database do
    desc 'migrate database'
    task :migrate do
    on roles(:db) do
    execute "cd #{release_path} && ./vendor/bin/
    doctrine-migrations migrations:migrate --db-configuration
    config/db-config.php --configuration config/migrations.yml"
    end
    end
    end

    View Slide

  46. @mheap
    lib/capistrano/tasks/database_tasks.rake:
    namespace :database do
    desc 'migrate database'
    task :migrate do
    on roles(:db) do
    execute "cd #{release_path} && ./vendor/bin/
    doctrine-migrations migrations:migrate --db-configuration
    config/db-config.php --configuration config/migrations.yml"
    end
    end
    end

    View Slide

  47. @mheap
    lib/capistrano/tasks/database_tasks.rake:
    namespace :database do
    desc 'migrate database'
    task :migrate do
    on roles(:db) do
    execute "cd #{release_path} && ./vendor/bin/
    doctrine-migrations migrations:migrate --db-configuration
    config/db-config.php --configuration config/migrations.yml"
    end
    end
    end

    View Slide

  48. @mheap
    Capfile:
    after "composer:install", "database:migrate"

    View Slide

  49. @mheap
    $ cap production deploy
    00:22 database:migrate
    01 cd #{release_path} && ./vendor/bin/doctrine-migrations
    migrations:migrate —db-co…
    ✔ 01 [email protected] 0.812s

    View Slide

  50. @mheap
    @mheap

    View Slide

  51. @mheap
    Useful tools
    Capistrano
    Webistrano
    Rocketeer
    Ansible

    View Slide

  52. @mheap
    1. One-click deployments
    2. Environment support
    3. Can only deploy from repo
    4. Internal solution
    5. Atomic deploys
    6. Rollback support
    1. Learning curve
    2. Composer run on server
    3. No build steps
    4. Probably want to use
    Bundler to manage versions
    Pros Cons

    View Slide

  53. @mheap
    Option C: System Packages

    View Slide

  54. @mheap
    $ apt-get install todo
    $ yum install todo
    $ pacman -S todo

    View Slide

  55. @mheap
    @mheap

    View Slide

  56. @mheap
    @mheap

    View Slide

  57. @mheap
    .
    !"" resources
    !"" src
    # !"" application
    # # !"" controller
    # # # $"" IndexController.php
    # # !"" model
    # # # $"" User.php
    # # $"" view
    # # $"" show-user.php
    # !"" composer.json
    # !"" composer.lock
    # !"" config
    # # !"" mappings.json
    # # $"" targets.json
    # $"" public
    # $"" index.php
    $"" test

    View Slide

  58. @mheap
    .
    !"" resources
    !"" src
    # !"" application
    # # !"" controller
    # # # $"" IndexController.php
    # # !"" model
    # # # $"" User.php
    # # $"" view
    # # $"" show-user.php
    # !"" composer.json
    # !"" composer.lock
    # !"" config
    # # !"" mappings.json
    # # $"" targets.json
    # $"" public
    # $"" index.php
    $"" test
    $ fpm -s dir -t rpm -n todo

    View Slide

  59. @mheap
    .
    !"" resources
    !"" src
    # !"" application
    # # !"" controller
    # # # $"" IndexController.php
    # # !"" model
    # # # $"" User.php
    # # $"" view
    # # $"" show-user.php
    # !"" composer.json
    # !"" composer.lock
    # !"" config
    # # !"" mappings.json
    # # $"" targets.json
    # $"" public
    # $"" index.php
    $"" test
    $ fpm -s dir -t rpm -n todo \
    src/=/var/www/todo \
    src/config/=/etc/todo

    View Slide

  60. @mheap
    .
    !"" resources
    !"" src
    # !"" application
    # # !"" controller
    # # # $"" IndexController.php
    # # !"" model
    # # # $"" User.php
    # # $"" view
    # # $"" show-user.php
    # !"" composer.json
    # !"" composer.lock
    # !"" config
    # # !"" mappings.json
    # # $"" targets.json
    # $"" public
    # $"" index.php
    $"" test
    $ fpm -s dir -t rpm --config-files /etc \
    -n todo \
    src/=/var/www/todo \
    src/config/=/etc/todo

    View Slide

  61. @mheap
    .
    !"" resources
    !"" src
    # !"" application
    # # !"" controller
    # # # $"" IndexController.php
    # # !"" model
    # # # $"" User.php
    # # $"" view
    # # $"" show-user.php
    # !"" composer.json
    # !"" composer.lock
    # !"" config
    # # !"" mappings.json
    # # $"" targets.json
    # $"" public
    # $"" index.php
    $"" test
    $ fpm -s dir -t rpm --config-files /etc \
    --exclude "var/www/todo/config*" \
    -n todo \
    src/=/var/www/todo \
    src/config/=/etc/todo

    View Slide

  62. @mheap
    $ fpm -s dir -t rpm --config-files /etc --exclude
    "var/www/todo/config*" -n todo src/=/var/
    www/todo src/config/=/etc/todo
    => Created package
    {:path=>"todo-1.0-1.x86_64.rpm"}

    View Slide

  63. @mheap
    Continous Integration

    View Slide

  64. @mheap
    What is
    Continous Integration?

    View Slide

  65. @mheap
    Use it to
    run tests

    View Slide

  66. @mheap
    Use it to
    composer install

    View Slide

  67. @mheap
    Use it to
    build on identical platforms

    View Slide

  68. @mheap
    Use it to
    package your application

    View Slide

  69. @mheap
    Use it to
    AUTOMATE THINGS

    View Slide

  70. @mheap
    @mheap

    View Slide

  71. @mheap
    Option C: System Packages

    View Slide

  72. @mheap
    Almost

    View Slide

  73. @mheap
    Database migrations

    View Slide

  74. @mheap
    $ fpm -s dir -t rpm --config-files /etc --exclude
    "var/www/todo/config*" -n todo src/=/var/
    www/todo src/config/=/etc/todo
    => Created package
    {:path=>"todo-1.0-1.x86_64.rpm"}

    View Slide

  75. @mheap
    $ fpm -s dir -t rpm --config-files /etc --exclude
    "var/www/todo/config*" -n todo
    --after-install /path/to/script src/=/var/www/
    todo src/config/=/etc/todo
    => Created package
    {:path=>"todo-1.0-1.x86_64.rpm"}

    View Slide

  76. @mheap
    Useful tools
    FPM
    Jenkins
    RPM / Deb / Pkg

    View Slide

  77. @mheap
    Releases are
    immutable

    View Slide

  78. @mheap
    1. Atomic releases
    2. Build on system tools
    3. Proper build toolchain
    4. Signed builds
    5. Easy upgrade/rollback
    6. Immutable
    1. Steep learning curve
    2. Need to run package repo
    3. Ideal to run CI system
    Pros Cons

    View Slide

  79. @mheap
    Option D: Blue / Green

    View Slide

  80. @mheap
    Load
    Balancer

    View Slide

  81. @mheap
    Load
    Balancer

    View Slide

  82. @mheap
    Load
    Balancer

    View Slide

  83. @mheap
    Shared databases

    View Slide

  84. @mheap
    Server maintenance

    View Slide

  85. @mheap
    Shameless Plug

    View Slide

  86. @mheap
    Infrastructure level

    View Slide

  87. @mheap
    Useful tools
    Puppet
    Chef
    Ansible

    View Slide

  88. @mheap
    1. Low risk deployments
    2. Test on production systems
    3. Easy changeover
    1. Can be expensive
    2. Databases are hard
    3. More moving parts to
    manage
    Pros Cons

    View Slide

  89. @mheap
    Option E: Immutable

    View Slide

  90. @mheap
    1 0 0
    1 0 1
    Load
    Balancer

    View Slide

  91. @mheap
    1 0 1
    Load
    Balancer

    View Slide

  92. @mheap
    1 0 1
    Load
    Balancer 1 0 2
    1 1 0

    View Slide

  93. @mheap
    Load
    Balancer
    1 0 1
    1 0 2
    1 1 0

    View Slide

  94. @mheap
    Load
    Balancer 1 0 2
    1 1 0

    View Slide

  95. @mheap
    Why immutable?

    View Slide

  96. @mheap
    Load
    Balancer
    1 0 0
    1 0 1

    View Slide

  97. @mheap
    1 0 0
    1 0 1
    Load
    Balancer

    View Slide

  98. @mheap
    1 0 0
    Load
    Balancer

    View Slide

  99. @mheap
    1 0 0
    Load
    Balancer
    1 0 2

    View Slide

  100. @mheap
    Useful tools
    Puppet / Chef / Ansible
    Packer
    Cloud providers

    View Slide

  101. @mheap
    1. Known environment
    2. Test 2+ releases at once
    3. Easy changeover
    4. Truly atomic releases
    1. Cost
    2. Slow to build
    3. Database sync
    Pros Cons

    View Slide

  102. @mheap
    Deployment techniques

    View Slide

  103. @mheap
    Build (at least) daily
    (even better if it’s automated)

    View Slide

  104. @mheap
    Announce releases

    View Slide

  105. @mheap
    Staggered Releases

    View Slide

  106. @mheap
    Canary deploys

    View Slide

  107. @mheap
    Go / No Go

    View Slide

  108. @mheap
    Containers

    View Slide

  109. @mheap
    Summary

    View Slide

  110. @mheap
    Automate your deployment

    View Slide

  111. @mheap
    Local builds

    View Slide

  112. @mheap
    Immutable releases

    View Slide

  113. @mheap
    Think about deployment
    before you write any code

    View Slide

  114. @mheap
    The three strikes rule

    View Slide

  115. @mheap
    Make it a single command

    View Slide

  116. @mheap
    Your deploys should be as boring,
    straightforward, and stress-free as
    possible.
    - Zach Holman
    (https://zachholman.com/posts/deploying-software)

    View Slide

  117. @mheap at #phptour
    https://joind.in/
    20636
    Michael Heap
    @mheap
    [email protected]

    View Slide