Skip to content

Commit b4ee385

Browse files
authored
Merge branch 'main' into 20240328_jg_chapter_09_review
2 parents 97e9f60 + 43c3c21 commit b4ee385

File tree

10 files changed

+94
-100
lines changed

10 files changed

+94
-100
lines changed

.git-blame-ignore-revs

Whitespace-only changes.

chapter_09_docker.asciidoc

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
[[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.
39

410
.A Note for Early Release Readers
511
****
@@ -107,7 +113,7 @@ Security and Configuration::
107113
(because they expose our source code in tracebacks).
108114

109115

110-
One way to approach the problem is to get a server,
116+
One way to approach the problem is to get a server
111117
and start manually configuring and installing everything,
112118
hacking about until it works,
113119
and maybe think about automating things laterfootnote:[
@@ -119,8 +125,8 @@ in the world of agile/lean software development,
119125
it's that taking smaller steps usually pays off.
120126

121127
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
124130
before we actually take the plunge?
125131
Can we then make small changes one at a time,
126132
solving problems one by one,
@@ -153,46 +159,46 @@ to customers outside the business.
153159

154160
So when you come to deploy your code to a real server in a datacentre,
155161
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,
157163
with software like Virtualbox or KVM.
158164

159165
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.
162168

163169
Conceptually, "regular" virtualization works at the hardware level:
164170
it gives you multiple virtual machines (VMs)
165171
that pretend to be physical computers, on a single real machine.
166172
So you can run multiple operating systems using separate VMs
167173
on the same physical box.
168174

169-
Containerization work at the operating system level:
175+
Containerization works at the operating system level:
170176
it gives you multiple virtual operating systems that
171177
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--
173179
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,
175181
using a single real host operating system and kernel.
176182

177183
Have a look at
178184
https://www.docker.com/resources/what-container/[Docker's resources on containers]
179-
for more explanation,
185+
for more explanation.
180186
The upshot of this is that containers are much "cheaper".
181187
You can start one up in milliseconds,
182188
and you can run hundreds on the same machine.
183189

184190

185191
==== Docker and your CV
186192

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,
189195
which, as always, is:
190196
"it's fashionable so it's going to look good on my CV."
191197

192198
For the purposes of this book,
193199
that's not such a bad justification really!
194200

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"
196202
deployment on our own machine, before we try the real one--but
197203
also, containers are so popular nowadays,
198204
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:
267273

268274
=== An Overview of Our Deployment Procedure
269275

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.
271277
It isn't meant to be the _perfect_ deployment procedure,
272278
so please don't take it as being best practice,
273279
or a recommendation--it's meant to be an illustration,
@@ -289,8 +295,7 @@ and where testing fits in.
289295
with passing tests.
290296

291297

292-
293-
298+
//RITA: Consider cross-referencing the chapter by number here so we can hyperlink it for convenience.
294299
**Next chapter: Moving to a production-ready configuration**
295300

296301
* Gradually, incrementally change the container configuration
@@ -302,7 +307,7 @@ and where testing fits in.
302307

303308
// gunicorn, DEBUG=False, secret key, etc
304309

305-
310+
//RITA: Consider cross-referencing the chapter by number here so we can hyperlink it for convenience.
306311
**Third chapter: Automating deployment to real servers**
307312

308313
* Gradually build up an Ansible playbook to deploy our containers on a real server.
@@ -333,20 +338,19 @@ called `TEST_SERVER`:
333338

334339

335340
[role="sourcecode"]
336-
.functional_tests/tests.py (ch08l001)
341+
.functional_tests/tests.py (ch09l001)
337342
====
338343
[source,python]
339344
----
340345
import os
341346
[...]
342347
343348
class NewVisitorTest(StaticLiveServerTestCase):
344-
345349
def setUp(self):
346350
self.browser = webdriver.Firefox()
347-
test_server = os.environ.get('TEST_SERVER') #<1>
351+
test_server = os.environ.get("TEST_SERVER") #<1>
348352
if test_server:
349-
self.live_server_url = 'http://' + test_server #<2>
353+
self.live_server_url = "http://" + test_server #<2>
350354
----
351355
====
352356

@@ -364,12 +368,11 @@ and to use a real server instead.
364368
<2> Here's the hack: we replace `self.live_server_url` with the address of
365369
our "real" server.
366370

367-
368-
NOTE: A clarification: in these chapters,
369-
we run tests _against_ our Docker container, or _against_ our staging server,
370-
but that doesn't mean we run the tests _from_ Docker or _from_ our staging server.
371-
We still run the tests from our own laptop,
372-
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.
373376

374377

375378
We test that said hack hasn't broken anything by running the functional
@@ -408,14 +411,13 @@ ERROR: test_can_start_a_todo_list
408411
(functional_tests.tests.NewVisitorTest.test_can_start_a_todo_list)
409412
---------------------------------------------------------------------
410413
Traceback (most recent call last):
411-
File "...goat-book/functional_tests/tests.py", line 31, in
414+
File "...goat-book/functional_tests/tests.py", line 38, in
412415
test_can_start_a_todo_list
413416
self.browser.get(self.live_server_url)
414417
[...]
418+
415419
selenium.common.exceptions.WebDriverException: Message: Reached error page: abo
416-
ut:neterror?e=connectionFailure&u=http%3A//localhost:8888/&c=UTF-8&
417-
f=regular&d=Firefox%20can%27t%20establish%20a%20connection%20to%20the%20server%
418-
20at%20localhost.
420+
ut:neterror?e=connectionFailure&u=http%3A//localhost:8888/[...]
419421
420422
421423
Ran 1 tests in 5.518s
@@ -491,7 +493,7 @@ Status: Downloaded newer image for busybox:latest
491493
hello world
492494
----
493495

494-
What's happened there is that Docker has
496+
What's happened there is that Docker has:
495497

496498
* Searched for a local copy of the "busybox" image and not found it
497499
* Downloaded the image from DockerHub
@@ -507,7 +509,7 @@ Cool! We'll find out more about all of these steps as the chapter progresses.
507509
Impartiality commands me to also recommend https://podman.io/[Podman],
508510
which is a like-for-like replacement for Docker.
509511
510-
It's pretty much exactly the same as docker,
512+
It's pretty much exactly the same as Docker,
511513
arguably with a few advantages even, but I won't go into detail here.
512514
513515
I actually tried it out on early drafts of this chapter and it worked perfectly well.
@@ -589,10 +591,10 @@ CMD python manage.py runserver <4>
589591
<2> The `COPY` instruction (the uppercase words are called "instructions")
590592
lets you copy files from your own computer into the container image.
591593
We use it to copy all our source code from the newly-created _src_ folder,
592-
into a similarly-named folder at the root of the container image
594+
into a similarly-named folder at the root of the container image.
593595

594596
<3> `WORKDIR` sets the current working directory for all subsequent commands.
595-
It's a bit like doing `cd /src`
597+
It's a bit like doing `cd /src`.
596598

597599
<4> Finally the `CMD` instruction tells docker which command you want it to run
598600
by default, when you start a container based on that image.
@@ -833,7 +835,7 @@ you should find the docker process has been terminated.
833835
834836
=== Using the FT to Check That Our Container Works
835837
836-
Let's see what our FTs think about this Docker version of our site.
838+
Let's see what our FTs think about this Docker version of our site:
837839
838840
839841
[role="small-code"]
@@ -846,13 +848,13 @@ selenium.common.exceptions.WebDriverException: Message: Reached error page:
846848
about:neterror?e=connectionFailure&u=http%3A//localhost%3A8888/[...]
847849
----
848850
849-
Nope! What's going on here? Time for a little debugging.
851+
What's going on here? Time for a little debugging.
850852
851853
852854
853855
=== Debugging a Container Networking Problems
854856
855-
First let's try and take a look ourselves, in our browser, by going to http://localhost:8888/:
857+
First, let's try and take a look ourselves, in our browser, by going to http://localhost:8888/:
856858
857859
[[firefox-unable-to-connect-screenshot]]
858860
.Cannot connect on that port
@@ -1023,6 +1025,7 @@ $ *docker build -t superlists . && docker run -p 8888:8888 -it superlists*
10231025
Now that will _change_ the error we see, but only quite subtly (see <<firefox-connection-reset>>).
10241026
Things clearly aren't working yet.
10251027
1028+
//RITA: If at all possible, I suggest using the light or daytime theme for all browser screenshots to make them easier to read.
10261029
[[firefox-connection-reset]]
10271030
.Cannot connect on that port
10281031
image::images/firefox-connection-reset.png["Firefox showing the 'Connection reset' error"]
@@ -1118,7 +1121,7 @@ $ *docker build -t superlists . && docker run -p 8888:8888 -it superlists*
11181121
Starting development server at http://0.0.0.0:8888/
11191122
----
11201123
1121-
We can verify it's working with `curl:
1124+
We can verify it's working with `curl`:
11221125
11231126
[subs="specialcharacters,macros"]
11241127
----
@@ -1147,7 +1150,7 @@ and say "well, this is hopeless, it can't be fixed",
11471150
and give up.
11481151
11491152
Thankfully I have had some good role models over the years
1150-
who are much better at it than me (hi Glenn!).
1153+
who are much better at it than me (hi, Glenn!).
11511154
Debugging needs the patience and tenacity of a bloodhound.
11521155
If at first you don't succeed,
11531156
you need to systematically rule out options,
@@ -1236,7 +1239,7 @@ Run 'python manage.py migrate' to apply them.
12361239
NOTE: If you don't see this error,
12371240
it's because your src folder had the database file in it, unlike mine.
12381241
For the sake of argument, run `rm src/db.sqlite3` and re-run the build & run commands,
1239-
and you should be able to repro the error. I promise it's instructive!
1242+
and you should be able to reproduce the error. I promise it's instructive!
12401243
12411244
12421245
==== Should we run "migrate" inside the Dockerfile? No. // JAN: Not sure I understand this line. You're saying that we shouldn't run migrate inside our Dockerfile, but then in the next line you do exactly that
@@ -1254,7 +1257,7 @@ If you try it, you'll find it certainly fixes the problem:
12541257
WORKDIR /src
12551258

12561259
RUN python manage.py migrate --noinput <1>
1257-
CMD python manage.py runserver
1260+
CMD python manage.py runserver 0.0.0.0:8888
12581261
----
12591262
====
12601263
@@ -1291,7 +1294,7 @@ For the purposes of this book, the easiest analogy to a server that's "outside"
12911294
is to access the database from the filesystem outside the container.
12921295
12931296
That also gives us a convenient excuse to talk about mounting files in Docker,
1294-
which is a very useful thing to be able to do (TM).
1297+
which is a very Useful Thing to be Able to Do (TM).
12951298
12961299
12971300
First let's revert our change:
@@ -1304,11 +1307,10 @@ First let's revert our change:
13041307
[...]
13051308
WORKDIR /src
13061309

1307-
CMD python manage.py runserver
1310+
CMD python manage.py runserver 0.0.0.0:8888
13081311
----
13091312
====
13101313
1311-
// JAN: I assume you meant to keep CMD python manage.py runserver 0.0.0.0:8888 as is and just remove migrations. Without that, port mapping won't work and server won't listen to external connections
13121314
13131315
Let's start by re-creating the database with `migrate`
13141316
(when we moved everything into `./src`, we left the database file behind):
@@ -1368,6 +1370,7 @@ Ran 3 tests in 26.965s
13681370
OK
13691371
----
13701372
1373+
//RITA: I'd rather add exclamation marks than extend the word.
13711374
AMAZING IT ACTUALLY WORKSSSSSSSS.
13721375
13731376
Ahem, that's definitely good enough for now! Let's commit.

0 commit comments

Comments
 (0)