Docker105 min total · 19 parts
Docker Fundamentals: Images, Containers, and Writing a Good Dockerfile
Part 1 of 19 · ~1 min
Overview
Marcus files the bug at nine in the morning: receipts stop parsing the moment he pulls the latest code. You try to reproduce it and can't — works fine on your machine. Priya tries too, and it also works for her, except a receipt scanned sideways comes out upside down, which it never does for you or Marcus. Three people, one bug report, three different sets of symptoms. By lunch you've worked out why: Marcus is still on Node 18 while you're on Node 20, and Priya's laptop is an aging Intel Mac while yours and Marcus's are both Apple Silicon — and the receipt-parsing library the three of you depend on behaves slightly differently depending on which of those it's compiled against.
Nobody did anything wrong. This is just what happens when "the application" and "the environment the application runs in" are treated as two separate things that every laptop is expected to line up by hand.
That's where this starts, and it's also roughly where it ends up. By the time snapledger is running in front of a paying customer, it will have hit a slow build caused by a bad cache order, a shutdown that silently takes ten seconds longer than it should, an image ten times bigger than it needs to be, a base-image swap that breaks in a way nobody's test data happened to catch, a startup race between two containers that both technically "started," and a two-in-the-morning page that comes down to a single three-digit exit code. Every one of those is a section below, in the order they actually happened. None of them is invented for the occasion — this is what taking one small, real app from three disagreeing laptops to a production server actually looks like, mechanism by mechanism.