1
1
[[chapter_09_docker]]
2
- == Deployment Part 1: Containerization aka Docker
2
+ == Containerization aka Docker
3
+ // RITA: I'm not keen on including the word "part" in chapter titles
4
+ // especially when the chapter is also within something called a "part."
5
+ // Would it make sense to put the deployment chapters into its own Part?
6
+ // So, ch8 might go into Part 1,
7
+ // chs 9-11 would go into the new Part 2 called something like "Deployment,"
8
+ // and Part 3 would start with ch 12.
3
9
4
10
.A Note for Early Release Readers
5
11
****
@@ -107,7 +113,7 @@ Security and Configuration::
107
113
(because they expose our source code in tracebacks).
108
114
109
115
110
- One way to approach the problem is to get a server,
116
+ One way to approach the problem is to get a server
111
117
and start manually configuring and installing everything,
112
118
hacking about until it works,
113
119
and maybe think about automating things laterfootnote:[
@@ -119,8 +125,8 @@ in the world of agile/lean software development,
119
125
it's that taking smaller steps usually pays off.
120
126
121
127
How can we take smaller, safer steps towards a production deployment?
122
- Can we _simulate_ the process of moving to a server,
123
- so that we can iron out all the bugs,
128
+ Can we _simulate_ the process of moving to a server
129
+ so that we can iron out all the bugs
124
130
before we actually take the plunge?
125
131
Can we then make small changes one at a time,
126
132
solving problems one by one,
@@ -153,46 +159,46 @@ to customers outside the business.
153
159
154
160
So when you come to deploy your code to a real server in a datacentre,
155
161
it will be using virtualization.
156
- And actually you can use virtualization on your own machine,
162
+ And, actually, you can use virtualization on your own machine,
157
163
with software like Virtualbox or KVM.
158
164
159
165
But that can be fiddly to set up!
160
- And nowadays, thanks to containerization, we can do better.
161
- Because containerization is a kind of even-more-virtual virtualization.
166
+ And nowadays, thanks to containerization, we can do better
167
+ because containerization is a kind of even-more-virtual virtualization.
162
168
163
169
Conceptually, "regular" virtualization works at the hardware level:
164
170
it gives you multiple virtual machines (VMs)
165
171
that pretend to be physical computers, on a single real machine.
166
172
So you can run multiple operating systems using separate VMs
167
173
on the same physical box.
168
174
169
- Containerization work at the operating system level:
175
+ Containerization works at the operating system level:
170
176
it gives you multiple virtual operating systems that
171
177
all run on a single real OS.
172
- It lets us pack the source code and its dependencies together,
178
+ It lets us pack the source code and its dependencies together--
173
179
the entire environment required to run the application.
174
- So you can run programs inside separate virtual environments,
180
+ This allows you to run programs inside separate virtual environments,
175
181
using a single real host operating system and kernel.
176
182
177
183
Have a look at
178
184
https://www.docker.com/resources/what-container/[Docker's resources on containers]
179
- for more explanation,
185
+ for more explanation.
180
186
The upshot of this is that containers are much "cheaper".
181
187
You can start one up in milliseconds,
182
188
and you can run hundreds on the same machine.
183
189
184
190
185
191
==== Docker and your CV
186
192
187
- That's all well and good for the _theoretical_ justification.
188
- But let's get to the _real_ reason for using this technology,
193
+ That's all well and good for the _theoretical_ justification,
194
+ but let's get to the _real_ reason for using this technology,
189
195
which, as always, is:
190
196
"it's fashionable so it's going to look good on my CV."
191
197
192
198
For the purposes of this book,
193
199
that's not such a bad justification really!
194
200
195
- Yes I think it's going to be a nice way to have a "pretend"
201
+ Yes, I think it's going to be a nice way to have a "pretend"
196
202
deployment on our own machine, before we try the real one--but
197
203
also, containers are so popular nowadays,
198
204
that it's very likely that you're going to encounter them at work
@@ -267,7 +273,7 @@ But there are solutions to all of these. In order:
267
273
268
274
=== An Overview of Our Deployment Procedure
269
275
270
- Over these three chapters, I'm going to go through _a_ deployment procedure.
276
+ Over the next three chapters, I'm going to go through _a_ deployment procedure.
271
277
It isn't meant to be the _perfect_ deployment procedure,
272
278
so please don't take it as being best practice,
273
279
or a recommendation--it's meant to be an illustration,
@@ -289,8 +295,7 @@ and where testing fits in.
289
295
with passing tests.
290
296
291
297
292
-
293
-
298
+ //RITA: Consider cross-referencing the chapter by number here so we can hyperlink it for convenience.
294
299
**Next chapter: Moving to a production-ready configuration**
295
300
296
301
* Gradually, incrementally change the container configuration
@@ -302,7 +307,7 @@ and where testing fits in.
302
307
303
308
// gunicorn, DEBUG=False, secret key, etc
304
309
305
-
310
+ //RITA: Consider cross-referencing the chapter by number here so we can hyperlink it for convenience.
306
311
**Third chapter: Automating deployment to real servers**
307
312
308
313
* Gradually build up an Ansible playbook to deploy our containers on a real server.
@@ -363,12 +368,11 @@ and to use a real server instead.
363
368
<2> Here's the hack: we replace `self.live_server_url` with the address of
364
369
our "real" server.
365
370
366
-
367
- NOTE: A clarification: in these chapters,
368
- we run tests _against_ our Docker container, or _against_ our staging server,
369
- but that doesn't mean we run the tests _from_ Docker or _from_ our staging server.
370
- We still run the tests from our own laptop,
371
- but they target the place that's running our code.
371
+ NOTE: A clarification: when we say we run tests _against_ our Docker container,
372
+ or _against_ our staging server,
373
+ that doesn't mean we run the tests _from_ Docker or _from_ our staging server.
374
+ We still run the tests from our own laptop,
375
+ but they target the place that's running our code.
372
376
373
377
374
378
We test that said hack hasn't broken anything by running the functional
@@ -489,7 +493,7 @@ Status: Downloaded newer image for busybox:latest
489
493
hello world
490
494
----
491
495
492
- What's happened there is that Docker has
496
+ What's happened there is that Docker has:
493
497
494
498
* Searched for a local copy of the "busybox" image and not found it
495
499
* Downloaded the image from DockerHub
@@ -505,7 +509,7 @@ Cool! We'll find out more about all of these steps as the chapter progresses.
505
509
Impartiality commands me to also recommend https://podman.io/[Podman],
506
510
which is a like-for-like replacement for Docker.
507
511
508
- It's pretty much exactly the same as docker ,
512
+ It's pretty much exactly the same as Docker ,
509
513
arguably with a few advantages even, but I won't go into detail here.
510
514
511
515
I actually tried it out on early drafts of this chapter and it worked perfectly well.
@@ -585,10 +589,10 @@ CMD python manage.py runserver <4>
585
589
<2> The `COPY` instruction (the uppercase words are called "instructions")
586
590
lets you copy files from your own computer into the container image.
587
591
We use it to copy all our source code from the newly-created _src_ folder,
588
- into a similarly-named folder at the root of the container image
592
+ into a similarly-named folder at the root of the container image.
589
593
590
594
<3> `WORKDIR` sets the current working directory for all subsequent commands.
591
- It's a bit like doing `cd /src`
595
+ It's a bit like doing `cd /src`.
592
596
593
597
<4> Finally the `CMD` instruction tells docker which command you want it to run
594
598
by default, when you start a container based on that image.
@@ -829,7 +833,7 @@ you should find the docker process has been terminated.
829
833
830
834
=== Using the FT to Check That Our Container Works
831
835
832
- Let's see what our FTs think about this Docker version of our site.
836
+ Let's see what our FTs think about this Docker version of our site:
833
837
834
838
835
839
[role="small-code"]
@@ -842,13 +846,13 @@ selenium.common.exceptions.WebDriverException: Message: Reached error page:
842
846
about:neterror?e=connectionFailure&u=http%3A//localhost%3A8888/[...]
843
847
----
844
848
845
- Nope! What's going on here? Time for a little debugging.
849
+ What's going on here? Time for a little debugging.
846
850
847
851
848
852
849
853
=== Debugging a Container Networking Problems
850
854
851
- First let's try and take a look ourselves, in our browser, by going to http://localhost:8888/:
855
+ First, let's try and take a look ourselves, in our browser, by going to http://localhost:8888/:
852
856
853
857
[[firefox-unable-to-connect-screenshot]]
854
858
.Cannot connect on that port
@@ -1019,6 +1023,7 @@ $ *docker build -t superlists . && docker run -p 8888:8888 -it superlists*
1019
1023
Now that will _change_ the error we see, but only quite subtly (see <<firefox-connection-reset>>).
1020
1024
Things clearly aren't working yet.
1021
1025
1026
+ //RITA: If at all possible, I suggest using the light or daytime theme for all browser screenshots to make them easier to read.
1022
1027
[[firefox-connection-reset]]
1023
1028
.Cannot connect on that port
1024
1029
image::images/firefox-connection-reset.png["Firefox showing the 'Connection reset' error"]
@@ -1114,7 +1119,7 @@ $ *docker build -t superlists . && docker run -p 8888:8888 -it superlists*
1114
1119
Starting development server at http://0.0.0.0:8888/
1115
1120
----
1116
1121
1117
- We can verify it's working with `curl:
1122
+ We can verify it's working with `curl` :
1118
1123
1119
1124
[subs="specialcharacters,macros"]
1120
1125
----
@@ -1143,7 +1148,7 @@ and say "well, this is hopeless, it can't be fixed",
1143
1148
and give up.
1144
1149
1145
1150
Thankfully I have had some good role models over the years
1146
- who are much better at it than me (hi Glenn!).
1151
+ who are much better at it than me (hi, Glenn!).
1147
1152
Debugging needs the patience and tenacity of a bloodhound.
1148
1153
If at first you don't succeed,
1149
1154
you need to systematically rule out options,
@@ -1232,7 +1237,7 @@ Run 'python manage.py migrate' to apply them.
1232
1237
NOTE: If you don't see this error,
1233
1238
it's because your src folder had the database file in it, unlike mine.
1234
1239
For the sake of argument, run `rm src/db.sqlite3` and re-run the build & run commands,
1235
- and you should be able to repro the error. I promise it's instructive!
1240
+ and you should be able to reproduce the error. I promise it's instructive!
1236
1241
1237
1242
1238
1243
==== Should we run "migrate" inside the Dockerfile? No.
@@ -1287,7 +1292,7 @@ For the purposes of this book, the easiest analogy to a server that's "outside"
1287
1292
is to access the database from the filesystem outside the container.
1288
1293
1289
1294
That also gives us a convenient excuse to talk about mounting files in Docker,
1290
- which is a very useful thing to be able to do (TM).
1295
+ which is a very Useful Thing to be Able to Do (TM).
1291
1296
1292
1297
1293
1298
First let's revert our change:
@@ -1365,6 +1370,7 @@ Ran 3 tests in 26.965s
1365
1370
OK
1366
1371
----
1367
1372
1373
+ //RITA: I'd rather add exclamation marks than extend the word.
1368
1374
AMAZING IT ACTUALLY WORKSSSSSSSS.
1369
1375
1370
1376
Ahem, that's definitely good enough for now! Let's commit.
0 commit comments