Slide 1

Slide 1 text

@mheap at #phptour A beginners guide to deployments

Slide 2

Slide 2 text

@mheap Let’s talk deployment

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

@mheap Deployment for beginners

Slide 5

Slide 5 text

@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

Slide 6

Slide 6 text

@mheap What is a deployment?

Slide 7

Slide 7 text

@mheap Code

Slide 8

Slide 8 text

@mheap Dependencies

Slide 9

Slide 9 text

@mheap Configuration

Slide 10

Slide 10 text

@mheap Database Migrations

Slide 11

Slide 11 text

@mheap Other Migrations

Slide 12

Slide 12 text

@mheap Assets

Slide 13

Slide 13 text

@mheap Post Install Tasks

Slide 14

Slide 14 text

@mheap We’re aiming for…

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

@mheap Our Codebase

Slide 17

Slide 17 text

@mheap Simple to do list application

Slide 18

Slide 18 text

@mheap Composer Silex Doctrine Migrations

Slide 19

Slide 19 text

@mheap Time to deploy!

Slide 20

Slide 20 text

@mheap Option A: External tool

Slide 21

Slide 21 text

@mheap @mheap

Slide 22

Slide 22 text

@mheap @mheap

Slide 23

Slide 23 text

@mheap @mheap

Slide 24

Slide 24 text

@mheap @mheap

Slide 25

Slide 25 text

@mheap @mheap

Slide 26

Slide 26 text

@mheap @mheap

Slide 27

Slide 27 text

@mheap @mheap

Slide 28

Slide 28 text

@mheap @mheap

Slide 29

Slide 29 text

@mheap @mheap

Slide 30

Slide 30 text

@mheap @mheap

Slide 31

Slide 31 text

@mheap Useful tools Beanstalkapp DeployHQ Laravel Forge

Slide 32

Slide 32 text

@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

Slide 33

Slide 33 text

@mheap Option B: Internal tool

Slide 34

Slide 34 text

@mheap @mheap

Slide 35

Slide 35 text

@mheap $ gem install capistrano

Slide 36

Slide 36 text

@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

Slide 37

Slide 37 text

@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'

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

@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

Slide 40

Slide 40 text

@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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

@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

Slide 43

Slide 43 text

@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

Slide 44

Slide 44 text

@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

Slide 45

Slide 45 text

@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

Slide 46

Slide 46 text

@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

Slide 47

Slide 47 text

@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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

@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

Slide 50

Slide 50 text

@mheap @mheap

Slide 51

Slide 51 text

@mheap Useful tools Capistrano Webistrano Rocketeer Ansible

Slide 52

Slide 52 text

@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

Slide 53

Slide 53 text

@mheap Option C: System Packages

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

@mheap @mheap

Slide 56

Slide 56 text

@mheap @mheap

Slide 57

Slide 57 text

@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

Slide 58

Slide 58 text

@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

Slide 59

Slide 59 text

@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

Slide 60

Slide 60 text

@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

Slide 61

Slide 61 text

@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

Slide 62

Slide 62 text

@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"}

Slide 63

Slide 63 text

@mheap Continous Integration

Slide 64

Slide 64 text

@mheap What is Continous Integration?

Slide 65

Slide 65 text

@mheap Use it to run tests

Slide 66

Slide 66 text

@mheap Use it to composer install

Slide 67

Slide 67 text

@mheap Use it to build on identical platforms

Slide 68

Slide 68 text

@mheap Use it to package your application

Slide 69

Slide 69 text

@mheap Use it to AUTOMATE THINGS

Slide 70

Slide 70 text

@mheap @mheap

Slide 71

Slide 71 text

@mheap Option C: System Packages

Slide 72

Slide 72 text

@mheap Almost

Slide 73

Slide 73 text

@mheap Database migrations

Slide 74

Slide 74 text

@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"}

Slide 75

Slide 75 text

@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"}

Slide 76

Slide 76 text

@mheap Useful tools FPM Jenkins RPM / Deb / Pkg

Slide 77

Slide 77 text

@mheap Releases are immutable

Slide 78

Slide 78 text

@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

Slide 79

Slide 79 text

@mheap Option D: Blue / Green

Slide 80

Slide 80 text

@mheap Load Balancer

Slide 81

Slide 81 text

@mheap Load Balancer

Slide 82

Slide 82 text

@mheap Load Balancer

Slide 83

Slide 83 text

@mheap Shared databases

Slide 84

Slide 84 text

@mheap Server maintenance

Slide 85

Slide 85 text

@mheap Shameless Plug

Slide 86

Slide 86 text

@mheap Infrastructure level

Slide 87

Slide 87 text

@mheap Useful tools Puppet Chef Ansible

Slide 88

Slide 88 text

@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

Slide 89

Slide 89 text

@mheap Option E: Immutable

Slide 90

Slide 90 text

@mheap 1 0 0 1 0 1 Load Balancer

Slide 91

Slide 91 text

@mheap 1 0 1 Load Balancer

Slide 92

Slide 92 text

@mheap 1 0 1 Load Balancer 1 0 2 1 1 0

Slide 93

Slide 93 text

@mheap Load Balancer 1 0 1 1 0 2 1 1 0

Slide 94

Slide 94 text

@mheap Load Balancer 1 0 2 1 1 0

Slide 95

Slide 95 text

@mheap Why immutable?

Slide 96

Slide 96 text

@mheap Load Balancer 1 0 0 1 0 1

Slide 97

Slide 97 text

@mheap 1 0 0 1 0 1 Load Balancer

Slide 98

Slide 98 text

@mheap 1 0 0 Load Balancer

Slide 99

Slide 99 text

@mheap 1 0 0 Load Balancer 1 0 2

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

@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

Slide 102

Slide 102 text

@mheap Deployment techniques

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

@mheap Announce releases

Slide 105

Slide 105 text

@mheap Staggered Releases

Slide 106

Slide 106 text

@mheap Canary deploys

Slide 107

Slide 107 text

@mheap Go / No Go

Slide 108

Slide 108 text

@mheap Containers

Slide 109

Slide 109 text

@mheap Summary

Slide 110

Slide 110 text

@mheap Automate your deployment

Slide 111

Slide 111 text

@mheap Local builds

Slide 112

Slide 112 text

@mheap Immutable releases

Slide 113

Slide 113 text

@mheap Think about deployment before you write any code

Slide 114

Slide 114 text

@mheap The three strikes rule

Slide 115

Slide 115 text

@mheap Make it a single command

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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