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