Skip to content

Commit f044060

Browse files
committed
Get 10 more or less into shape
1 parent 8c29ad4 commit f044060

File tree

3 files changed

+59
-67
lines changed

3 files changed

+59
-67
lines changed

chapter_10_production_readiness.asciidoc

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -57,32 +57,44 @@ an ORM, all sorts of middleware, the admin site...
5757
"What else do you want, a pony?" Well, Gunicorn stands for "Green Unicorn",
5858
which I guess is what you'd want next if you already had a pony...
5959

60+
//001
61+
cmdg
62+
63+
64+
[subs="specialcharacters,quotes"]
6065
----
61-
pip install gunicorn
62-
pip freeze | grep -i gunicorn== >> requirements.txt
66+
$ *pip install gunicorn*
67+
Collecting gunicorn
68+
[...]
69+
Successfully installed gunicorn-21.2.0
70+
$ *pip freeze | grep -i gunicorn== >> requirements.txt*
6371
----
6472

6573
Gunicorn will need to know a path to a WSGI server,
6674
which is usually a function called `application`.
6775
Django provides one in 'superlists/wsgi.py':
6876

77+
[role="sourcecode"]
78+
.Dockerfile (ch10l002)
79+
====
80+
[source,Dockerfile]
6981
----
70-
CMD ["gunicorn", "--bind", ":8888", "superlists.wsgi:application"]
82+
CMD gunicorn --bind :8888 superlists.wsgi:application
7183
----
72-
73-
// TODO mention new cmd syntax with ["list"]
74-
84+
====
7585

7686
As in the previous chapter, we can use the `docker build && docker run`
7787
pattern to try out our changes by rebuilding and rerunning our container:
7888

89+
[subs="specialcharacters,quotes"]
7990
----
8091
$ *docker build -t superlists . && docker run \
8192
-p 8888:8888 \
8293
-v ./src/db.sqlite3:/src/db.sqlite3 \
8394
-it superlists*
8495
----
8596

97+
8698
==== The FTs catch a problem with static files
8799

88100
As we run the functional tests, you'll see them warning us of a problem, once again.
@@ -101,7 +113,7 @@ FAILED (failures=1)
101113
And indeed, if you take a look at the site, you'll find the CSS is all broken,
102114
as in <<site-with-broken-css>>.
103115

104-
The reason that the CSS is broken is that although the Django dev server will
116+
The reason that we have no CSS is that although the Django dev server will
105117
serve static files magically for you, Gunicorn doesn't.
106118

107119

@@ -170,8 +182,9 @@ OK
170182

171183
Phew. Let's commit that
172184

185+
[subs="specialcharacters,quotes"]
173186
----
174-
*git commit -am"Switch to Gunicorn and Whitenoise"*
187+
$ *git commit -am"Switch to Gunicorn and Whitenoise"*
175188
----
176189

177190

@@ -182,12 +195,6 @@ We know there are several things in
182195
_settings.py_ that we want to change for production:
183196

184197

185-
////
186-
* +ALLOWED_HOSTS+ is currently set to "*" which isn't secure. We want it
187-
to be set to only match the site we're supposed to be serving
188-
(_localhost_ for now, but someday soon, a real domain).
189-
////
190-
191198
* `DEBUG` mode is all very well for hacking about on your own server,
192199
but it https://docs.djangoproject.com/en/1.11/ref/settings/#debug[isn't secure].
193200
For example, exposing raw tracebacks to the world is a bad idea.
@@ -205,7 +212,7 @@ Development, staging and production sites always have some differences
205212
in their configuration.
206213
Environment variables are a good place to store those different settings.
207214
See http://www.clearlytech.com/2014/01/04/12-factor-apps-plain-english/[
208-
"the 12-factor app"].footnote:[
215+
"The 12-Factor App"].footnote:[
209216
Another common way of handling this
210217
is to have different versions of _settings.py_ for dev and prod.
211218
That can work fine too, but it can get confusing to manage.
@@ -269,31 +276,34 @@ Now let's set that environment variable in our Dockerfile using then `ENV` direc
269276
WORKDIR /src
270277
271278
ENV DJANGO_DEBUG_FALSE=1
272-
CMD ["gunicorn", "--bind", ":8888", "superlists.wsgi:application"]
279+
CMD gunicorn --bind :8888 superlists.wsgi:application
273280
----
274281
====
275282

276283
And try it out...
277284

278285

279286

287+
[subs="specialcharacters,macros"]
280288
----
281-
$ *docker build -t superlists . && docker run \
289+
$ pass:quotes[*docker build -t superlists . && docker run \
282290
-p 8888:8888 \
283291
-v ./src/db.sqlite3:/src/db.sqlite3 \
284-
-it superlists*
292+
-it superlists*]
285293
286294
[...]
295+
File "/src/superlists/settings.py", line 22, in <module>
287296
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
288297
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
289-
# TODO: show more of traceback
298+
File "<frozen os>", line 685, in __getitem__
299+
KeyError: 'DJANGO_SECRET_KEY'
290300
----
291301

292302
Ooops, and I forgot to set said secret key env var,
293303
mere seconds after having dreamt it up!
294304

295305

296-
==== Setting environment variables at the docker command-line
306+
==== Setting Environment Variables at the Docker Command Line
297307

298308
We've said we can't keep the secret key in our source code,
299309
so the Dockerfile isn't an option; where else can we put it?
@@ -427,7 +437,7 @@ WORKDIR /src
427437
RUN python manage.py collectstatic
428438
429439
ENV DJANGO_DEBUG_FALSE=1
430-
CMD ["gunicorn", "--bind", ":8888", "superlists.wsgi:application"]
440+
CMD gunicorn --bind :8888 superlists.wsgi:application
431441
----
432442
====
433443

@@ -444,12 +454,17 @@ OK
444454

445455
We have a container that we're ready to ship to production!
446456

447-
Find out how in the next exciting installment.
457+
Find out how in the next exciting installment...
448458

449459

460+
////
450461
=== TODO: log files
451462
452-
provoke a 500 error somehow and make sure we see tracebacks for it
463+
provoke a 500 error somehow and make sure we see tracebacks for it?
464+
465+
docker logs might be enough.
466+
alternatively, mount logfiles from host.
467+
////
453468

454469

455470
[role="pagebreak-before less_space"]
@@ -469,7 +484,7 @@ Decide how to serve your static files::
469484
that comes from Django and your webapp, so they need to be treated differently.
470485
WhiteNoise is just one example of how you might do that.
471486
472-
Check your settings.py for dev-only settings::
487+
Check your settings.py for dev-only config::
473488
`DEBUG=True`, `ALLOWED_HOSTS` and `SECRET_KEY` are the ones we came across,
474489
but you will probably have others
475490
(we'll see more when we start to send emails from the server).
@@ -480,21 +495,5 @@ Change things one at a time and rerun your tests frequently::
480495
and either be confident that everything works as well as it did before,
481496
or find out immediately if we did something wrong.
482497
483-
Security::
484-
A serious discussion of server security is beyond the scope of this book,
485-
and I'd warn against running your own servers
486-
without learning a good bit more about it.
487-
(One reason people choose to use a PaaS to host their code
488-
is that it means a slightly fewer security issues to worry about.)
489-
If you'd like a place to start, here's as good a place as any:
490-
https://plusbryan.com/my-first-5-minutes-on-a-server-or-essential-security-for-linux-servers[My first 5 minutes on a server].
491-
I can definitely recommend the eye-opening experience of installing
492-
fail2ban and watching its logfiles to see just how quickly it picks up on
493-
random drive-by attempts to brute force your SSH login. The internet is a
494-
wild place!
495-
((("security issues and settings", "server security")))
496-
((("Platform-As-A-Service (PaaS)")))
497-
498-
TODO: that last one probably belongs in the next chapter.
499498
500499
*******************************************************************************

chapter_11_ansible.asciidoc

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -663,37 +663,30 @@ Here are some resources I used for inspiration:
663663
.Automated Deployments
664664
*******************************************************************************
665665
666-
Fabric::
667-
((("automated deployment", "best practices for")))((("Fabric", "automated deployment best practices")))Fabric
668-
lets you run commands on servers from inside Python scripts. This
669-
is a great tool for automating server admin tasks.
670-
671-
672666
Idempotency::
673-
((("idempotency")))If
674-
your deployment script is deploying to existing servers, you need to
675-
design them so that they work against a fresh installation 'and' against
676-
a server that's already configured.
677-
678-
679-
Keep config files under source control::
680-
Make sure your only copy of a config file isn't on the server! They
681-
are critical to your application, and should be under version control
682-
like anything else.
667+
If your deployment script is deploying to existing servers, you need to
668+
design them so that they work against a fresh installation 'and' against
669+
a server that's already configured.
670+
((("idempotency")))
683671
684672
Automating provisioning::
685-
Ultimately, 'everything' should be automated, and that includes spinning up
673+
Ultimately, _everything_ should be automated, and that includes spinning up
686674
brand new servers and ensuring they have all the right software installed.
687675
This will involve interacting with the API of your hosting provider.
688676
689-
Configuration management tools::
690-
((("configuration management tools")))
691-
((("Ansible")))
692-
Fabric is very flexible, but its logic is still based on scripting. More
693-
advanced tools take a more "declarative" approach, and can make your life
694-
even easier. Ansible and Vagrant are two worth checking out (see
695-
<<appendix3>>), but there are many more (Chef, Puppet, Salt, Juju...).
696-
((("", startref="Dfarbric11")))
677+
Security::
678+
A serious discussion of server security is beyond the scope of this book,
679+
and I'd warn against running your own servers
680+
without learning a good bit more about it.
681+
(One reason people choose to use a PaaS to host their code
682+
is that it means a slightly fewer security issues to worry about.)
683+
If you'd like a place to start, here's as good a place as any:
684+
https://plusbryan.com/my-first-5-minutes-on-a-server-or-essential-security-for-linux-servers[My first 5 minutes on a server].
685+
I can definitely recommend the eye-opening experience of installing
686+
fail2ban and watching its logfiles to see just how quickly it picks up on
687+
random drive-by attempts to brute force your SSH login. The internet is a
688+
wild place!
689+
((("security issues and settings", "server security")))
690+
((("Platform-As-A-Service (PaaS)")))
697691
698692
*******************************************************************************
699-

0 commit comments

Comments
 (0)