Slide 1

Slide 1 text

A presentation by @stuherbert
 for @GanbaroDigital Designing Docker Containers For PHP App Development

Slide 2

Slide 2 text

Industry veteran: architect, engineer, leader, manager, mentor F/OSS contributor since 1994 Talking and writing about PHP since 2004 Chief Software Archaeologist @GanbaroDigital About Stuart

Slide 3

Slide 3 text

Follow me I do tweet a lot about non-tech stuff though :) @stuherbert

Slide 4

Slide 4 text

@GanbaroDigital This isn’t a “What Is Docker?” talk, nor a “Why Docker?” talk.

Slide 5

Slide 5 text

@GanbaroDigital This is more a “How to Dockerize?” talk.

Slide 6

Slide 6 text

@GanbaroDigital The underlying principles apply to any containerised application.

Slide 7

Slide 7 text

@GanbaroDigital Why am I giving this talk?

Slide 8

Slide 8 text

@GanbaroDigital This is a follow-up to my talk Docker for PHP Dev Environments presented @PHPMinds in 2017

Slide 9

Slide 9 text

@GanbaroDigital https://speakerdeck.com/stuartherbert/ docker-for-php-dev-environments

Slide 10

Slide 10 text

@GanbaroDigital I’ve been working with clients who want to Dockerize everything. The same points come up every time.

Slide 11

Slide 11 text

@GanbaroDigital Containers are different to virtual machines

Slide 12

Slide 12 text

@GanbaroDigital Your data if you lift and shift a VM into a container

Slide 13

Slide 13 text

@GanbaroDigital “ Some things change, and some things stay the same.

Slide 14

Slide 14 text

@GanbaroDigital This is my experience. This is how I do it, and why.

Slide 15

Slide 15 text

@GanbaroDigital Other approaches exist. I’m here to learn from you too!

Slide 16

Slide 16 text

@GanbaroDigital Please ask questions as we go.

Slide 17

Slide 17 text

@GanbaroDigital In This Talk ... 1. Common Understanding 2. Image and Container Properties 3. Putting It All Together 4. Common Questions

Slide 18

Slide 18 text

@GanbaroDigital Common Understanding

Slide 19

Slide 19 text

@GanbaroDigital “ Docker’s terminology can be very confusing when you’re starting out.

Slide 20

Slide 20 text

@GanbaroDigital ?? ?? What do we mean when we talk about containers and images?

Slide 21

Slide 21 text

@GanbaroDigital A Docker image is a blueprint that has been built.

Slide 22

Slide 22 text

@GanbaroDigital The blueprint is the Dockerfile.

Slide 23

Slide 23 text

@GanbaroDigital A Docker container is a running instance of a Docker image.

Slide 24

Slide 24 text

@GanbaroDigital You can spin up many containers from the same image.

Slide 25

Slide 25 text

@GanbaroDigital Image & Container Properties

Slide 26

Slide 26 text

@GanbaroDigital “ Things are easier when something is used in the way it was intended.

Slide 27

Slide 27 text

@GanbaroDigital Image Properties

Slide 28

Slide 28 text

@GanbaroDigital Image Properties Include ... • Distribution • Layering

Slide 29

Slide 29 text

@GanbaroDigital Image Properties Include ... • Distribution • Layering

Slide 30

Slide 30 text

@GanbaroDigital https://flic.kr/p/SgsXBV Distribution

Slide 31

Slide 31 text

@GanbaroDigital An image is a thing that you can distribute. Just like a VBOX file.

Slide 32

Slide 32 text

@GanbaroDigital Docker Hub

Slide 33

Slide 33 text

@GanbaroDigital You can use the same image in dev, test, & production to guarantee the same behaviour everywhere.

Slide 34

Slide 34 text

@GanbaroDigital “ You don’t want the same behaviour in dev, test & production.

Slide 35

Slide 35 text

@GanbaroDigital You can use the same image in dev, test, & production to guarantee the same behaviour everywhere.

Slide 36

Slide 36 text

@GanbaroDigital You can use the same image in dev, test, & production to guarantee the same software everywhere.

Slide 37

Slide 37 text

@GanbaroDigital ?? ?? What differences do we want?

Slide 38

Slide 38 text

@GanbaroDigital “Dev images are optimised for developer productivity. Test / prod images are optimised for production use.

Slide 39

Slide 39 text

@GanbaroDigital Differences Wanted ... • Logging levels • PHP profiler modules • PHP opcache config • Baking your app into the image

Slide 40

Slide 40 text

@GanbaroDigital Differences Wanted ... • Logging levels • PHP profiler modules • PHP opcache config • Baking your app into the image

Slide 41

Slide 41 text

@GanbaroDigital Differences Wanted ... • Logging levels • PHP profiler modules • PHP opcache config • Baking your app into the image

Slide 42

Slide 42 text

@GanbaroDigital Differences Wanted ... • Logging levels • PHP profiler modules • PHP opcache config • Baking your app into the image

Slide 43

Slide 43 text

@GanbaroDigital https://flic.kr/p/FQ4jk9 Layering

Slide 44

Slide 44 text

@GanbaroDigital Docker images are layered.

Slide 45

Slide 45 text

@GanbaroDigital

Slide 46

Slide 46 text

@GanbaroDigital “Docker images are layered. Generalise base layers, specialise later layers.

Slide 47

Slide 47 text

@GanbaroDigital Container Properties

Slide 48

Slide 48 text

@GanbaroDigital Container Properties Include ... • Co-location • Non-persistence • Customisation • Copy-on-write filesystem

Slide 49

Slide 49 text

@GanbaroDigital Container Properties Include ... • Co-location • Non-persistence • Customisation • Copy-on-write filesystem

Slide 50

Slide 50 text

@GanbaroDigital Container Properties Include ... • Co-location • Non-persistence • Customisation • Copy-on-write filesystem

Slide 51

Slide 51 text

@GanbaroDigital Container Properties Include ... • Co-location • Non-persistence • Customisation • Copy-on-write filesystem

Slide 52

Slide 52 text

@GanbaroDigital https://flic.kr/p/94KBK1 Co-location

Slide 53

Slide 53 text

@GanbaroDigital ?? ?? What can you run inside a Docker container?

Slide 54

Slide 54 text

@GanbaroDigital Anything you choose. (Almost)

Slide 55

Slide 55 text

@GanbaroDigital And as many things as you want.

Slide 56

Slide 56 text

@GanbaroDigital “ You can co-locate multiple processes inside a single container.

Slide 57

Slide 57 text

@GanbaroDigital https://flic.kr/p/ab5xJY Non-persistence

Slide 58

Slide 58 text

@GanbaroDigital Persistence is the ability to survive the destruction and re-creation of a Docker container.

Slide 59

Slide 59 text

@GanbaroDigital It’s normal to destroy Docker containers and then re-create them from the underlying Docker image.

Slide 60

Slide 60 text

@GanbaroDigital When you destroy a Docker container, you lose everything you’ve saved inside that container.

Slide 61

Slide 61 text

@GanbaroDigital “ The contents of a Docker container are not persistent.

Slide 62

Slide 62 text

@GanbaroDigital The contents of a Docker container are not persistent.

Slide 63

Slide 63 text

@GanbaroDigital Your data if you lift and shift a VM into a container

Slide 64

Slide 64 text

@GanbaroDigital ?? ?? What kinds of persistent data does your app create?

Slide 65

Slide 65 text

@GanbaroDigital Persistent Data Includes ... • Databases • File uploads • Session data • Auto-upgrades / plugin installs (Wordpress) • Logs

Slide 66

Slide 66 text

@GanbaroDigital Persistent Data Includes ... • Databases • File uploads • Session data • Auto-upgrades / plugin installs (Wordpress) • Logs

Slide 67

Slide 67 text

@GanbaroDigital Persistent Data Includes ... • Databases • File uploads • Session data • Auto-upgrades / plugin installs (Wordpress) • Logs

Slide 68

Slide 68 text

@GanbaroDigital Persistent Data Includes ... • Databases • File uploads • Session data • Auto-upgrades / plugin installs (Wordpress) • Logs

Slide 69

Slide 69 text

@GanbaroDigital Persistent Data Includes ... • Databases • File uploads • Session data • Auto-upgrades / plugin installs (Wordpress) • Logs

Slide 70

Slide 70 text

@GanbaroDigital We can mount persistent data volumes into containers.

Slide 71

Slide 71 text

@GanbaroDigital

Slide 72

Slide 72 text

@GanbaroDigital https://flic.kr/p/j6mk6C Customised

Slide 73

Slide 73 text

@GanbaroDigital Docker containers can write to their filesystems.

Slide 74

Slide 74 text

@GanbaroDigital We can use that to customise config files when a Docker container starts up.

Slide 75

Slide 75 text

@GanbaroDigital ?? ?? Why might we want to modify config files at startup?

Slide 76

Slide 76 text

@GanbaroDigital Nginx

Slide 77

Slide 77 text

@GanbaroDigital “ A one-time startup script can tailor your container.

Slide 78

Slide 78 text

@GanbaroDigital https://flic.kr/p/64YX6u COW Filesystem

Slide 79

Slide 79 text

@GanbaroDigital Docker containers use a copy-on-write filesystem.

Slide 80

Slide 80 text

@GanbaroDigital Writes are slow, and if you hit them hard enough, they break.

Slide 81

Slide 81 text

@GanbaroDigital “ After startup, write as little as possible to a Docker container’s filesystem.

Slide 82

Slide 82 text

@GanbaroDigital 5 Key Design Questions • How can I break my image up into layers? • What does my app need? • How do I configure everything? • Where will persistent data go? • How do I avoid all other writes to the FS?

Slide 83

Slide 83 text

@GanbaroDigital Putting It All Together

Slide 84

Slide 84 text

@GanbaroDigital https://github.com/ganbarodigital/docker-images/

Slide 85

Slide 85 text

@GanbaroDigital The Base Image

Slide 86

Slide 86 text

@GanbaroDigital Base Ubuntu Server

Slide 87

Slide 87 text

@GanbaroDigital • Your (minimal) operating system of choice • + anything all your child images regularly need • + convenience tools for when (not if) you shell into the containers • + standardise volume mount points

Slide 88

Slide 88 text

@GanbaroDigital “Get it right in the base layer. Don’t have to put it right further up in your image stack.

Slide 89

Slide 89 text

@GanbaroDigital Supervisord

Slide 90

Slide 90 text

@GanbaroDigital /etc/supervisor/supervisord.conf

Slide 91

Slide 91 text

@GanbaroDigital /etc/supervisor/conf.d/nginx.conf

Slide 92

Slide 92 text

@GanbaroDigital /usr/local/sbin/image-startup.sh

Slide 93

Slide 93 text

@GanbaroDigital Dockerfile: standardise side-load mount points

Slide 94

Slide 94 text

@GanbaroDigital Web Server

Slide 95

Slide 95 text

@GanbaroDigital Base Web Server Ubuntu Server Nginx or Apache

Slide 96

Slide 96 text

@GanbaroDigital • Your web server of choice • + default config files

Slide 97

Slide 97 text

@GanbaroDigital Nginx default site

Slide 98

Slide 98 text

@GanbaroDigital Nginx default site

Slide 99

Slide 99 text

@GanbaroDigital Why A Web Server Image? • Standalone use: static sites • Shared basis: PHP, Python, Ruby, etc etc

Slide 100

Slide 100 text

@GanbaroDigital Runtime

Slide 101

Slide 101 text

@GanbaroDigital Base Web Server PHP Ubuntu Server Nginx or Apache PHP-FPM or mod_php

Slide 102

Slide 102 text

@GanbaroDigital • This is where your language runtime goes • + supporting config files

Slide 103

Slide 103 text

@GanbaroDigital https://flic.kr/p/94KBK1 Co-location Example

Slide 104

Slide 104 text

@GanbaroDigital “ PHP goes in the same Docker container as your web server.

Slide 105

Slide 105 text

@GanbaroDigital ?? ?? What happens if you run Apache/Nginx and PHP in separate containers?

Slide 106

Slide 106 text

@GanbaroDigital Physical Server Apache mod_php

Slide 107

Slide 107 text

@GanbaroDigital Physical Server Apache mod_php

Slide 108

Slide 108 text

@GanbaroDigital Apache + mod_php • mod_php runs inside the Apache process • You can’t split a single process across two containers

Slide 109

Slide 109 text

@GanbaroDigital Container Apache mod_php

Slide 110

Slide 110 text

@GanbaroDigital ?? ?? What about Apache/Nginx + PHP-FPM?

Slide 111

Slide 111 text

@GanbaroDigital Apache/Nginx and PHP-FPM are separate processes.

Slide 112

Slide 112 text

@GanbaroDigital We can split separate processes into separate containers. All the early advice was: 1 process per container

Slide 113

Slide 113 text

@GanbaroDigital

Slide 114

Slide 114 text

@GanbaroDigital Physical Server

Slide 115

Slide 115 text

@GanbaroDigital Apache Physical Server

Slide 116

Slide 116 text

@GanbaroDigital Apache PHP-FPM Physical Server

Slide 117

Slide 117 text

@GanbaroDigital ?? ?? How do they talk to each other?

Slide 118

Slide 118 text

@GanbaroDigital Apache PHP-FPM unix domain socket (very fast) Physical Server

Slide 119

Slide 119 text

@GanbaroDigital Apache PHP-FPM unix domain socket (very fast) Container #1

Slide 120

Slide 120 text

@GanbaroDigital Not really any different to Apache/Nginx + PHP-FPM performance on a physical server.

Slide 121

Slide 121 text

@GanbaroDigital Apache PHP-FPM unix domain socket (very fast) Container #1

Slide 122

Slide 122 text

@GanbaroDigital Apache PHP-FPM Container #1 Container #2

Slide 123

Slide 123 text

@GanbaroDigital ?? ?? How do they talk to each other?

Slide 124

Slide 124 text

@GanbaroDigital Apache PHP-FPM Virtualised network
 (not as fast) Container #1 Container #2

Slide 125

Slide 125 text

@GanbaroDigital Virtualised network
 (not as fast) Container #1 Container #2 Apache PHP-FPM

Slide 126

Slide 126 text

@GanbaroDigital “ Co-locate all the things that you’d never put on separate physical servers.

Slide 127

Slide 127 text

@GanbaroDigital “ Separate all the things that would stop you scaling horizontally.

Slide 128

Slide 128 text

@GanbaroDigital This generic PHP image is my dev image.

Slide 129

Slide 129 text

@GanbaroDigital Base Application
 (if applicable)

Slide 130

Slide 130 text

@GanbaroDigital Base Web Server PHP Wordpress Ubuntu Server Nginx or Apache PHP-FPM or mod_php Base application

Slide 131

Slide 131 text

@GanbaroDigital • This layer is optional • Build a vanilla image for your base app (e.g. Wordpress, Magento) • Add in any common plugins/modules • Use as the base for multiple customisations down the road

Slide 132

Slide 132 text

@GanbaroDigital Your App

Slide 133

Slide 133 text

@GanbaroDigital Base Web Server PHP Wordpress Your App Ubuntu Server Nginx or Apache PHP-FPM or mod_php Base application Profit :)

Slide 134

Slide 134 text

@GanbaroDigital Final layer is your code.

Slide 135

Slide 135 text

@GanbaroDigital Base Web Server PHP Wordpress Your App Ubuntu Server Nginx or Apache PHP-FPM or mod_php Base application Profit :)

Slide 136

Slide 136 text

@GanbaroDigital ?? ?? Can we add more layers?

Slide 137

Slide 137 text

@GanbaroDigital You could add one more layer, for customer-specific customisation.

Slide 138

Slide 138 text

@GanbaroDigital

Slide 139

Slide 139 text

@GanbaroDigital Common Questions

Slide 140

Slide 140 text

@GanbaroDigital 3 Common Questions • Databases inside containers • SSH servers • Port forwarding

Slide 141

Slide 141 text

@GanbaroDigital ?? ?? Can you run a database server (e.g. MySQL, MongoDB) inside a container?

Slide 142

Slide 142 text

@GanbaroDigital Yes. As long as they store all data on a persistent volume.

Slide 143

Slide 143 text

@GanbaroDigital Databases do not need to be co-located with your app. So run them in their own container.

Slide 144

Slide 144 text

@GanbaroDigital ?? ?? Should you run an SSH server in each Docker container?

Slide 145

Slide 145 text

@GanbaroDigital I don’t any more.

Slide 146

Slide 146 text

@GanbaroDigital • Most of my containers are behind a proxy or load balancer of some kind. • Can’t reach them from an off-host network. • One less thing to worry about.

Slide 147

Slide 147 text

@GanbaroDigital A lot of the advice out there is built around port forwarding. I prefer to run my containers with their own IP addresses.

Slide 148

Slide 148 text

@GanbaroDigital Summing Up

Slide 149

Slide 149 text

@GanbaroDigital 5 Key Design Questions • How can I break my image up into layers? • What does my app need? • How do I configure everything? • Where will persistent data go? • How do I avoid all other writes to the FS?

Slide 150

Slide 150 text

@GanbaroDigital “ You don’t want the same behaviour in dev, test & production.

Slide 151

Slide 151 text

@GanbaroDigital “Dev images are optimised for developer productivity. Test / prod images are optimised for production use.

Slide 152

Slide 152 text

@GanbaroDigital “Docker images are layered. Generalise base layers, specialise later layers.

Slide 153

Slide 153 text

@GanbaroDigital Base Web Server PHP Wordpress Your App Ubuntu Server Nginx or Apache PHP-FPM or mod_php Base application Profit :)

Slide 154

Slide 154 text

@GanbaroDigital “Get it right in the base layer. Don’t have to put it right further up in your image stack.

Slide 155

Slide 155 text

@GanbaroDigital “Standardise where things go. /config /data /logs & /workspace

Slide 156

Slide 156 text

@GanbaroDigital “ A one-time startup script can tailor your container.

Slide 157

Slide 157 text

@GanbaroDigital “ After startup, write as little as possible to a Docker container’s filesystem.

Slide 158

Slide 158 text

@GanbaroDigital “ Co-locate all the things that you’d never put on separate physical servers.

Slide 159

Slide 159 text

@GanbaroDigital “ Separate all the things that would stop you scaling horizontally.

Slide 160

Slide 160 text

@GanbaroDigital “ The contents of a Docker container are not persistent.

Slide 161

Slide 161 text

@GanbaroDigital The contents of a Docker container are not persistent.

Slide 162

Slide 162 text

@GanbaroDigital Your data if you lift and shift a VM into a container

Slide 163

Slide 163 text

@GanbaroDigital https://github.com/ganbarodigital/docker-images/

Slide 164

Slide 164 text

Thank You Any Questions? A presentation by @stuherbert
 for @GanbaroDigital