
Lessons from Building Node Apps in Docker - JohnHammersley
https://jdlm.info/articles/2019/09/06/lessons-building-node-app-docker.html
======
peterwwillis
If you're going to run these containers in production [on more than a single
host], throw out the volumes and docker compose. Mock up your dev sdlc to work
like production (ex. you can't use Docker Compose to start Fargate tasks)

In fact, I'm going to make a very heretical suggestion and say, don't even
start writing app code until you know exactly how your whole SDLC, deployment
workflow, architecture, etc will work in production. Figure out all that crap
right at the start. You'll have a lot of extra considerations you didn't think
of before, like container and app security scanning, artifact repository,
source of truth for deployment versions, quality gates, different pipelines
for dev and prod, orchestration system, deployment strategy, release process,
secrets management, backup, access control, network requirements, service
accounts, monitoring, etc.

The reason to map all that out up front is to "shift left". If you do these
things one at a time, you lose more time later as you slowly implement each
piece, refactoring as you go. Whereas if you know everything you're going to
have to do, you have much better estimates of work. It's like doing sprint
grooming but much farther ahead. Figure out potential problems sooner and it
saves your butt down the road. (You can still change everything as you go, but
your estimates will be wayyyy closer to reality, and you'll need less rework)

A weird comparison would be trying to build wooden furniture without planning
out how you were gonna build it. You can get it done, but you have no idea if
it'll take a weekend or two months. Plan it out and you can get more done in
one shot, and the quality even improves. This is also the principle behind
_mise en place_.

~~~
beardedman
I don't think you're worrying about the right things here if you're about to
start writing app code. Infrastructure can be changed easily - poorly
architected code cannot.

~~~
peterwwillis
What I'm talking about isn't infrastructure, it's the entire system
architecture and workflow. Code architecture is a part of that. If you design
your code architecture, and _then_ look at system architecture, your code
architecture may have to change. I'm suggesting to do them at the same time.

Say you did your code architecture, and you've been writing code for 3 months.
The security architect comes by and takes a look at your work, and announces
that your design is inherently flawed; you need to fix some token-passing
thing that's tied deeply into your app to support some system they have to
audit company apps. You end up doing rework for a sprint or 2 to fix it. This
in particular may not apply to you, but there are hundreds of examples like
this.

------
ypeter
Why do you run the final production container with a node (slim) image and not
just nginx? Would be another 6 times smaller.

~~~
thenewnewguy
They are running JavaScript as server code, not just serving JS files for a
client.

------
rcarmo
In case anyone needs ARM containers for node, I build my own LTS containers on
Travis:

[https://github.com/insightfulsystems/alpine-
node](https://github.com/insightfulsystems/alpine-node)

...and use those as the base for most of my stuff in order to have a bit more
control over what goes in the images:

[https://github.com/insightfulsystems/node-
red](https://github.com/insightfulsystems/node-red)

------
ne01
The fact that you need to learn so many lessons while using docker shows how
complex it is.

~~~
mirekrusin
Those lessons are highly subjective. You can use docker in production with 5%
of this info. Ie I’m personally not a fan of using docker locally for
development. I use it sometimes to boot local dependencies but never direct
project I’m currently working on.

~~~
toyg
What is the point of having docker at all, then, if development and production
deployments are so different...?

Not trying to be flippant here - I am genuinely still trying to get my head
around docker’s popularity, it’s just so awkward in so many cases...

~~~
eropple
I test and deploy in Docker containers because the artifact that's produced is
simpler to deal with. I don't have to specify packages in a Chef cookbook or
Ansible playbook, then figure out how to best automate the running of those,
_then_ figure out how to do it fast enough to support rapid deploys. And while
I run Fedora locally, it presents an abstraction layer that's sufficient, in
the 99% case, that developers on a Mac can test predictably; as a trivial
example, the Dockerfile specifies an informal but strong interface with
regards to environment variables, configuration files, and network ports.
(That goes down to like 95% with Windows, but I haven't worked on it with WSL2
yet.)

Treating Docker containers as artifacts--as Configurable, Better Tarballs--
_by itself_ is a significant improvement for much of the non-JVM world, and
even does have some benefits for the JVM world as well.

Trying to do local dev in it is silly, IMO, but there's real value to shipping
Docker containers to wherever you want to actually run the thing.

------
iquestionshard
Is there a benefit to why you'd `npm install` in docker? I would likely have
already done that in the checkout and test part of my workflow, and can just
copy everything over from that?

~~~
jordiburgos
That is done to have a complete and repeatable build. If that is run on a
different machine will still work the same.

------
chrisweekly
Thanks, @JohnHammersley! Your 2016 writeup of the same name was well-received;
given how fast things change in this space, I'd bet this "updated for 2019"
version is worth bookmarking.

~~~
JohnHammersley
Thanks Chris, but I should point out that I'm not the author of the blog post
(that's my good friend @jdleesmiller) :)

------
dang
Related from 2016:
[https://news.ycombinator.com/item?id=11545975](https://news.ycombinator.com/item?id=11545975)

