Skip to content

Commit cfe4223

Browse files
authored
Rita edits to ch 9
1 parent b1a2836 commit cfe4223

File tree

1 file changed

+41
-37
lines changed

1 file changed

+41
-37
lines changed

chapter_09_docker.asciidoc

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[[chapter_09_docker]]
22
== Deployment Part 1: Containerization aka Docker
3+
// RITA: I'm not keen on including the word "part" in chapter titles especially when the chapter is also within something called a "part." Would it make sense to put the deployment chapters into its own Part? So, ch8 might go into Part 1, chs 9-11 would go into the new Part 2 called something like "Deployment," and Part 3 would start with ch 12.
34

45
[quote, 'http://bit.ly/2uhCXnH[Devops Borat]']
56
______________________________________________________________
@@ -97,7 +98,7 @@ Security and Configuration::
9798
(because they expose our source code in tracebacks).
9899

99100

100-
One way to approach the problem is to get a server,
101+
One way to approach the problem is to get a server
101102
and start manually configuring and installing everything,
102103
hacking about until it works,
103104
and maybe think about automating things laterfootnote:[
@@ -109,8 +110,8 @@ in the world of agile/lean software development,
109110
it's that taking smaller steps usually pays off.
110111

111112
How can we take smaller, safer steps towards a production deployment?
112-
Can we _simulate_ the process of moving to a server,
113-
so that we can iron out all the bugs,
113+
Can we _simulate_ the process of moving to a server
114+
so that we can iron out all the bugs
114115
before we actually take the plunge?
115116
Can we then make small changes one at a time,
116117
solving problems one by one,
@@ -134,7 +135,7 @@ sometimes referred to as "containerization".
134135
You may have already heard of the idea of "virtualization",
135136
which allows a single physical computer to pretend to be several machines.
136137
Pioneered by IBM (amongst others) on mainframes in the 1960s,
137-
it rose to mainstream adoption in the 90s,
138+
it rose to mainstream adoption in the 1990s,
138139
where it was sold as a way to optimise resource usage in datacentres.
139140
AWS, for example, was an offshoot of Amazon,
140141
who were using virtualization already,
@@ -143,46 +144,46 @@ to customers outside the business.
143144

144145
So when you come to deploy your code to a real server in a datacentre,
145146
it will be using virtualization.
146-
And actually you can use virtualization on your own machine,
147+
And, actually, you can use virtualization on your own machine,
147148
with software like Virtualbox or KVM.
148149

149150
But that can be fiddly to set up!
150-
And nowadays, thanks to containerization, we can do better.
151-
Because containerization is a kind of even-more-virtual virtualization.
151+
And nowadays, thanks to containerization, we can do better
152+
because containerization is a kind of even-more-virtual virtualization.
152153

153154
Conceptually, "regular" virtualization works at the hardware level:
154155
it gives you multiple virtual machines (VMs)
155156
that pretend to be physical computers, on a single real machine.
156157
So you can run multiple operating systems using separate VMs
157158
on the same physical box.
158159

159-
Containerization work at the operating system level:
160+
Containerization works at the operating system level:
160161
it gives you multiple virtual operating systems that
161162
all run on a single real OS.
162-
It lets us pack the source code and its dependencies together,
163+
It lets us pack the source code and its dependencies together--
163164
the entire environment required to run the application.
164-
So you can run programs inside separate virtual environments,
165+
This allows you to run programs inside separate virtual environments,
165166
using a single real host operating system and kernel.
166167

167168
Have a look at
168169
https://www.docker.com/resources/what-container/[Docker's resources on containers]
169-
for more explanation,
170+
for more explanation.
170171
The upshot of this is that containers are much "cheaper".
171172
You can start one up in milliseconds,
172173
and you can run hundreds on the same machine.
173174

174175

175176
==== Docker and your CV
176177

177-
That's all well and good for the _theoretical_ justification.
178-
But let's get to the _real_ reason for using this technology,
178+
That's all well and good for the _theoretical_ justification,
179+
but let's get to the _real_ reason for using this technology,
179180
which, as always, is:
180181
"it's fashionable so it's going to look good on my CV."
181182

182183
For the purposes of this book,
183184
that's not such a bad justification really!
184185

185-
Yes I think it's going to be a nice way to have a "pretend"
186+
Yes, I think it's going to be a nice way to have a "pretend"
186187
deployment on our own machine, before we try the real one--but
187188
also, containers are so popular nowadays,
188189
that it's very likely that you're going to encounter them at work
@@ -257,7 +258,7 @@ But there are solutions to all of these. In order:
257258

258259
=== An Overview of Our Deployment Procedure
259260

260-
Over these three chapters, I'm going to go through _a_ deployment procedure.
261+
Over the next three chapters, I'm going to go through _a_ deployment procedure.
261262
It isn't meant to be the _perfect_ deployment procedure,
262263
so please don't take it as being best practice,
263264
or a recommendation--it's meant to be an illustration,
@@ -280,7 +281,7 @@ and where testing fits in.
280281

281282

282283

283-
284+
//RITA: Consider cross-referencing the chapter by number here so we can hyperlink it for convenience.
284285
**Next chapter: Moving to a production-ready configuration**
285286

286287
* Gradually, incrementally change the container configuration
@@ -292,7 +293,7 @@ and where testing fits in.
292293

293294
// gunicorn, DEBUG=False, secret key, etc
294295

295-
296+
//RITA: Consider cross-referencing the chapter by number here so we can hyperlink it for convenience.
296297
**Third chapter: Automating deployment to real servers**
297298

298299
* Gradually build up an Ansible playbook to deploy our containers on a real server.
@@ -354,8 +355,8 @@ and to use a real server instead.
354355
<2> Here's the hack: we replace `self.live_server_url` with the address of
355356
our "real" server.
356357

357-
358-
NOTE: A clarification: in these chapters,
358+
// RITA: In the next three chapters or the chapters in the book as a whole?
359+
NOTE: A clarification: In these chapters,
359360
we run tests _against_ our Docker container, or _against_ our staging server,
360361
but that doesn't mean we run the tests _from_ Docker or _from_ our staging server.
361362
We still run the tests from our own laptop,
@@ -481,7 +482,7 @@ Status: Downloaded newer image for busybox:latest
481482
hello world
482483
----
483484

484-
What's happened there is that Docker has
485+
What's happened there is that Docker has:
485486

486487
* Searched for a local copy of the "busybox" image and not found it
487488
* Downloaded the image from DockerHub
@@ -497,7 +498,7 @@ Cool! We'll find out more about all of these steps as the chapter progresses.
497498
Impartiality commands me to also recommend https://podman.io/[Podman],
498499
which is a like-for-like replacement for Docker.
499500
500-
It's pretty much exactly the same as docker,
501+
It's pretty much exactly the same as Docker,
501502
arguably with a few advantages even, but I won't go into detail here.
502503
503504
I actually tried it out on early drafts of this chapter and it worked perfectly well.
@@ -576,10 +577,10 @@ CMD python manage.py runserver <4>
576577
<2> The `COPY` instruction (the uppercase words are called "instructions")
577578
lets you copy files from your own computer into the container image.
578579
We use it to copy all our source code from the newly-created _src_ folder,
579-
into a similarly-named folder at the root of the container image
580+
into a similarly-named folder at the root of the container image.
580581

581582
<3> `WORKDIR` sets the current working directory for all subsequent commands.
582-
It's a bit like doing `cd /src`
583+
It's a bit like doing `cd /src`.
583584

584585
<4> Finally the `CMD` instruction tells docker which command you want it to run
585586
by default, when you start a container based on that image.
@@ -723,7 +724,7 @@ $ *git commit -m "Add requirements.txt for virtualenv"*
723724
You may be wondering why we didn't add our other dependency,
724725
Selenium, to our requirements,
725726
or why we didn't just add _all_ the dependencies,
726-
including the "transitive" ones (eg, Django has its own dependencies of `asgiref` and `sqlparse`).
727+
including the "transitive" ones (e.g., Django has its own dependencies of `asgiref` and `sqlparse`).
727728

728729
As always, I have to gloss over some nuance and tradeoffs,
729730
but the short answer is first, Selenium is only a dependency for the tests,
@@ -734,7 +735,7 @@ in more tools, and I didn't want to do that for this book.footnote:[
734735
When you have a moment, you might want to do some further reading
735736
on "lockfiles", pyproject.toml, hard pinning vs soft pining,
736737
and immediate vs transitive dependencies. If I absolutely _had_
737-
to recommend a python dependency management tool,
738+
to recommend a Python dependency management tool,
738739
it would be https://github.com/jazzband/pip-tools[pip-tools],
739740
which is a fairly minimal one.]
740741

@@ -791,8 +792,8 @@ TIP: Forgetting the `-r` and running `pip install requirements.txt`
791792
==== Successful Run
792793

793794
Let's do the `build` and `run` in a single line.
794-
This is a pattern I used quite often when developing a Dockerfile,
795-
to be able to quickly rebuild and see the effect of a change:
795+
This is a pattern I used quite often when developing a Dockerfile so I can
796+
quickly rebuild and see the effect of a change:
796797

797798
[subs="specialcharacters,quotes"]
798799
----
@@ -876,7 +877,7 @@ you should find the docker process has been terminated.
876877

877878
=== Using the FT to Check That Our Container Works
878879

879-
Let's see what our FTs think about this Docker version of our site.
880+
Let's see what our FTs think about this Docker version of our site:
880881

881882

882883
[role="small-code"]
@@ -889,13 +890,13 @@ selenium.common.exceptions.WebDriverException: Message: Reached error page:
889890
about:neterror?e=connectionFailure&u=http%3A//localhost%3A8888/[...]
890891
----
891892

892-
Nope! What's going on here? Time for a little debugging.
893+
What's going on here? Time for a little debugging.
893894

894895

895896

896897
=== Debugging a Container Networking Problems
897898

898-
First let's try and take a look ourselves, in our browser, by going to http://localhost:8888/:
899+
First, let's try and take a look ourselves, in our browser, by going to http://localhost:8888/:
899900

900901
[[firefox-unable-to-connect-screenshot]]
901902
.Cannot connect on that port
@@ -927,7 +928,7 @@ WORKDIR /src
927928
CMD python manage.py runserver 8888
928929
----
929930
====
930-
931+
//RITA: Newbie question. What does Ctrl+C do again? Add a couple of words to give us some quick context. "Use Ctrl+C to kill the current..."
931932
Ctrl+C the current dockerized container process if it's still running in your terminal,
932933
then give it another `build && run`:
933934

@@ -1066,6 +1067,7 @@ $ *docker build -t superlists . && docker run -p 8888:8888 -it superlists*
10661067
Now that will _change_ the error we see, but only quite subtly (see <<firefox-connection-reset>>).
10671068
Things clearly aren't working yet.
10681069

1070+
//RITA: If at all possible, I suggest using the light or daytime theme for all browser screenshots to make them easier to read.
10691071
[[firefox-connection-reset]]
10701072
.Cannot connect on that port
10711073
image::images/firefox-connection-reset.png["Firefox showing the 'Connection reset' error"]
@@ -1150,7 +1152,7 @@ $ *docker build -t superlists . && docker run -p 8888:8888 -it superlists*
11501152
Starting development server at http://0.0.0.0:8888/
11511153
----
11521154

1153-
We can verify it's working with `curl:
1155+
We can verify it's working with `curl`:
11541156

11551157
[subs="specialcharacters,macros"]
11561158
----
@@ -1179,7 +1181,7 @@ and say "well, this is hopeless, it can't be fixed",
11791181
and give up.
11801182
11811183
Thankfully I have had some good role models over the years
1182-
who are much better at it than me (hi Glenn!).
1184+
who are much better at it than me (hi, Glenn!).
11831185
Debugging needs the patience and tenacity of a bloodhound.
11841186
If at first you don't succeed,
11851187
you need to systematically rule out options,
@@ -1268,7 +1270,7 @@ Run 'python manage.py migrate' to apply them.
12681270
NOTE: If you don't see this error,
12691271
it's because your src folder had the database file in it, unlike mine.
12701272
For the sake of argument, run `rm src/db.sqlite3` and re-run the build & run commands,
1271-
and you should be able to repro the error. I promise it's instructive!
1273+
and you should be able to reproduce the error. I promise it's instructive!
12721274

12731275

12741276
==== Should we run "migrate" inside the Dockerfile? No.
@@ -1324,6 +1326,7 @@ is to access the database from the filesystem outside the container.
13241326

13251327
That also gives us a convenient excuse to talk about mounting files in Docker,
13261328
which is a very useful thing to be able to do (TM).
1329+
//RITA: If you're going to be funny with a (TM), then I suggest you take it further by using caps for the term. "A Very Useful Thing to Be Able to Do (TM)."
13271330

13281331

13291332
First let's revert our change:
@@ -1369,7 +1372,7 @@ ERRO[0000] error waiting for container: context canceled
13691372
////
13701373

13711374

1372-
TIP: if you see an error saying: `django.db.utils.OperationalError`: "unable to open database file",
1375+
TIP: If you see an error saying: `django.db.utils.OperationalError`: "unable to open database file",
13731376
try stopping the container, `rm -rf src/db.sqlite3`, then re-run the migrate command
13741377
_outside_ the container, and then rebuild and run your image.
13751378

@@ -1391,7 +1394,8 @@ Ran 3 tests in 26.965s
13911394
OK
13921395
----
13931396

1394-
AMAZING IT ACTUALLY WORKSSSSSSSS.
1397+
//RITA: I'd rather add exclamation marks than extend the word.
1398+
AMAZING! IT ACTUALLY WORKS!
13951399

13961400
Ahem, that's definitely good enough for now! Let's commit.
13971401

@@ -1408,7 +1412,7 @@ but now we can be reassured that the basic Docker plumbing works.
14081412
Notice that the FT was able to guide us incrementally towards a working config,
14091413
and spot problems early on (like the missing database).
14101414

1411-
But we really can't be using the Django dev server in production,
1415+
However, we really can't be using the Django dev server in production,
14121416
or running on port 8888 forever.
14131417
In the next chapter, we'll make our hacky image more production-ready.
14141418

0 commit comments

Comments
 (0)