[{"data":1,"prerenderedAt":513},["ShallowReactive",2],{"mdc-f1rmgm-key":3,"mdc--mgrmot-key":29,"mdc-udlam5-key":181,"mdc--2we4s-key":203,"mdc--9zwvw0-key":215,"mdc-qb1231-key":287,"mdc-a7dy4-key":297,"mdc-ehwlkr-key":324,"mdc--48gdqh-key":452,"mdc--gu24vo-key":467,"mdc-yp1af-key":496},{"data":4,"body":5},{},{"type":6,"children":7},"root",[8,16],{"type":9,"tag":10,"props":11,"children":12},"element","p",{},[13],{"type":14,"value":15},"text","Docker is not a container. Docker is a set of tools for building, shipping, and running containers — and the distinction matters, because the container is a kernel feature and Docker is the ergonomics wrapped around it.",{"type":9,"tag":10,"props":17,"children":18},{},[19,21,27],{"type":14,"value":20},"If you have taken ",{"type":9,"tag":22,"props":23,"children":24},"em",{},[25],{"type":14,"value":26},"Containers From Scratch",{"type":14,"value":28},", you have already built one by hand: namespaces, cgroups, a copy-on-write filesystem, nine commands. This course is the other direction. Everything here is what those nine commands became once someone made them pleasant to use.",{"data":30,"body":31},{},{"type":6,"children":32},[33,40,54],{"type":9,"tag":34,"props":35,"children":37},"h2",{"id":36},"the-pieces",[38],{"type":14,"value":39},"The pieces",{"type":9,"tag":10,"props":41,"children":42},{},[43,45,52],{"type":14,"value":44},"Running ",{"type":9,"tag":46,"props":47,"children":49},"code",{"className":48},[],[50],{"type":14,"value":51},"docker run",{"type":14,"value":53}," involves four things, and knowing which is which saves a lot of confused debugging:",{"type":9,"tag":55,"props":56,"children":57},"table",{},[58,77],{"type":9,"tag":59,"props":60,"children":61},"thead",{},[62],{"type":9,"tag":63,"props":64,"children":65},"tr",{},[66,72],{"type":9,"tag":67,"props":68,"children":69},"th",{},[70],{"type":14,"value":71},"Piece",{"type":9,"tag":67,"props":73,"children":74},{},[75],{"type":14,"value":76},"What it is",{"type":9,"tag":78,"props":79,"children":80},"tbody",{},[81,107,133,165],{"type":9,"tag":63,"props":82,"children":83},{},[84,94],{"type":9,"tag":85,"props":86,"children":87},"td",{},[88],{"type":9,"tag":89,"props":90,"children":91},"strong",{},[92],{"type":14,"value":93},"The CLI",{"type":9,"tag":85,"props":95,"children":96},{},[97,99,105],{"type":14,"value":98},"the ",{"type":9,"tag":46,"props":100,"children":102},{"className":101},[],[103],{"type":14,"value":104},"docker",{"type":14,"value":106}," command you type. It talks to the daemon over a socket, and can talk to a daemon on another machine.",{"type":9,"tag":63,"props":108,"children":109},{},[110,128],{"type":9,"tag":85,"props":111,"children":112},{},[113,118,120,126],{"type":9,"tag":89,"props":114,"children":115},{},[116],{"type":14,"value":117},"The daemon",{"type":14,"value":119}," (",{"type":9,"tag":46,"props":121,"children":123},{"className":122},[],[124],{"type":14,"value":125},"dockerd",{"type":14,"value":127},")",{"type":9,"tag":85,"props":129,"children":130},{},[131],{"type":14,"value":132},"the long-running process that actually does the work. Holds your images, containers, networks, volumes.",{"type":9,"tag":63,"props":134,"children":135},{},[136,144],{"type":9,"tag":85,"props":137,"children":138},{},[139],{"type":9,"tag":89,"props":140,"children":141},{},[142],{"type":14,"value":143},"containerd + runc",{"type":9,"tag":85,"props":145,"children":146},{},[147,149,155,157,163],{"type":14,"value":148},"what the daemon delegates to. ",{"type":9,"tag":46,"props":150,"children":152},{"className":151},[],[153],{"type":14,"value":154},"containerd",{"type":14,"value":156}," manages container lifecycle; ",{"type":9,"tag":46,"props":158,"children":160},{"className":159},[],[161],{"type":14,"value":162},"runc",{"type":14,"value":164}," is the thing that actually calls the kernel.",{"type":9,"tag":63,"props":166,"children":167},{},[168,176],{"type":9,"tag":85,"props":169,"children":170},{},[171],{"type":9,"tag":89,"props":172,"children":173},{},[174],{"type":14,"value":175},"A registry",{"type":9,"tag":85,"props":177,"children":178},{},[179],{"type":14,"value":180},"where images live when they are not on your machine. Docker Hub by default.",{"data":182,"body":183},{},{"type":6,"children":184},[185,190],{"type":9,"tag":186,"props":187,"children":189},"terminal-teaser",{":lines":188},"[{\"cmd\":\"docker version --format '{{.Client.Version}} / {{.Server.Version}}'\",\"out\":\"29.7.2 / 29.7.2\"},{\"cmd\":\"docker run --rm hello-world\",\"out\":\"Unable to find image 'hello-world:latest' locally\\nlatest: Pulling from library/hello-world\\nStatus: Downloaded newer image for hello-world:latest\\nHello from Docker!\"}]",[],{"type":9,"tag":10,"props":191,"children":192},{},[193,195,201],{"type":14,"value":194},"Read what that second command actually did. The image was not present, so the CLI asked the daemon, the daemon pulled it from Docker Hub, unpacked it, created a container from it, ran it, and the container exited. ",{"type":9,"tag":46,"props":196,"children":198},{"className":197},[],[199],{"type":14,"value":200},"--rm",{"type":14,"value":202}," then deleted the container. Five distinct operations behind one word.",{"data":204,"body":205},{},{"type":6,"children":206},[207],{"type":9,"tag":208,"props":209,"children":214},"quiz",{":answer":210,":options":211,"explanation":212,"question":213},"0","[\"The CLI is installed and working, but the daemon it talks to isn't running or isn't reachable\",\"Docker is not installed\",\"The image you asked for does not exist\"]","The CLI got far enough to try. It is a separate program from the daemon and they talk over a socket, so the CLI being fine tells you nothing about the daemon. Usually the fix is starting the service — or, on Linux, that your user is not in the `docker` group and cannot open the socket.","You run a Docker command and get \"Cannot connect to the Docker daemon\". What does that tell you?",[],{"data":216,"body":217},{},{"type":6,"children":218},[219,225,230,242,254,266],{"type":9,"tag":34,"props":220,"children":222},{"id":221},"images-and-containers-are-different-things",[223],{"type":14,"value":224},"Images and containers are different things",{"type":9,"tag":10,"props":226,"children":227},{},[228],{"type":14,"value":229},"This is the single most useful distinction in Docker, and it is worth being pedantic about because almost every confusing error message depends on it.",{"type":9,"tag":10,"props":231,"children":232},{},[233,235,240],{"type":14,"value":234},"An ",{"type":9,"tag":89,"props":236,"children":237},{},[238],{"type":14,"value":239},"image",{"type":14,"value":241}," is a read-only stack of filesystem layers plus metadata saying what to run. It is inert. It is a template.",{"type":9,"tag":10,"props":243,"children":244},{},[245,247,252],{"type":14,"value":246},"A ",{"type":9,"tag":89,"props":248,"children":249},{},[250],{"type":14,"value":251},"container",{"type":14,"value":253}," is a running (or stopped) instance of an image, with a thin writable layer on top. You can create fifty containers from one image; they share every byte of the image and differ only in what they have written.",{"type":9,"tag":255,"props":256,"children":260},"pre",{"className":257,"code":259,"language":14},[258],"language-text","docker images        # the templates you have\ndocker ps            # the running instances\ndocker ps -a         # ...including the stopped ones\n",[261],{"type":9,"tag":46,"props":262,"children":264},{"__ignoreMap":263},"",[265],{"type":14,"value":259},{"type":9,"tag":10,"props":267,"children":268},{},[269,271,277,279,285],{"type":14,"value":270},"The relationship is exactly class-and-object, or program-and-process. ",{"type":9,"tag":46,"props":272,"children":274},{"className":273},[],[275],{"type":14,"value":276},"docker rmi",{"type":14,"value":278}," deletes a template; ",{"type":9,"tag":46,"props":280,"children":282},{"className":281},[],[283],{"type":14,"value":284},"docker rm",{"type":14,"value":286}," deletes an instance. Deleting an image that a container still uses fails, for the same reason you cannot delete a program's binary out from under a running process.",{"data":288,"body":289},{},{"type":6,"children":290},[291],{"type":9,"tag":208,"props":292,"children":296},{":answer":210,":options":293,"explanation":294,"question":295},"[\"No — the edit lived in the first container's writable layer, and the image was never touched\",\"Yes — changes are saved back into the image automatically\",\"Only if you ran the container with `--rm`\"]","Images are read-only. Every write goes to the container's own thin layer and dies with it. Persisting anything on purpose means a volume, and baking something into the image means a rebuild — both covered later in this course.","You edit a file inside a running container, then stop it and start a fresh container from the same image. Is your edit there?",[],{"data":298,"body":299},{},{"type":6,"children":300},[301,307,319],{"type":9,"tag":34,"props":302,"children":304},{"id":303},"one-kernel-no-vm",[305],{"type":14,"value":306},"One kernel, no VM",{"type":9,"tag":10,"props":308,"children":309},{},[310,312,317],{"type":14,"value":311},"Worth stating plainly because the intuition points the wrong way: ",{"type":9,"tag":89,"props":313,"children":314},{},[315],{"type":14,"value":316},"a Linux container shares the host's kernel.",{"type":14,"value":318}," There is no guest operating system inside an image and no hypervisor underneath.",{"type":9,"tag":10,"props":320,"children":321},{},[322],{"type":14,"value":323},"That is why an Alpine image is eight megabytes — it contains a userland, not an OS. It is why a container starts in milliseconds instead of the tens of seconds a VM takes. And it is why Docker on macOS and Windows runs a Linux VM in the background: Linux containers need a Linux kernel, so if the host has not got one, one is provided.",{"data":325,"body":326},{},{"type":6,"children":327},[328],{"type":9,"tag":329,"props":330,"children":332},"deep-dive",{"title":331},"Where the images actually live now",[333,345,350,431],{"type":9,"tag":10,"props":334,"children":335},{},[336,338,343],{"type":14,"value":337},"Docker Engine 29.0 changed a default that had been in place for a decade: ",{"type":9,"tag":89,"props":339,"children":340},{},[341],{"type":14,"value":342},"the containerd image store is now the default on fresh installations",{"type":14,"value":344},", replacing the legacy graph drivers.",{"type":9,"tag":10,"props":346,"children":347},{},[348],{"type":14,"value":349},"This is mostly invisible, and where it is visible it is an improvement:",{"type":9,"tag":351,"props":352,"children":353},"ul",{},[354,389,421],{"type":9,"tag":355,"props":356,"children":357},"li",{},[358,363,365,371,373,379,381,387],{"type":9,"tag":89,"props":359,"children":360},{},[361],{"type":14,"value":362},"Multi-platform images can be held locally.",{"type":14,"value":364}," The old store could only keep one architecture per tag, which is why building a multi-arch image used to mean pushing it straight to a registry to see it. ",{"type":9,"tag":46,"props":366,"children":368},{"className":367},[],[369],{"type":14,"value":370},"docker image save",{"type":14,"value":372}," and ",{"type":9,"tag":46,"props":374,"children":376},{"className":375},[],[377],{"type":14,"value":378},"docker image load",{"type":14,"value":380}," now take ",{"type":9,"tag":46,"props":382,"children":384},{"className":383},[],[385],{"type":14,"value":386},"--platform",{"type":14,"value":388}," and understand multiple platforms.",{"type":9,"tag":355,"props":390,"children":391},{},[392,403,405,411,413,419],{"type":9,"tag":89,"props":393,"children":394},{},[395,401],{"type":9,"tag":46,"props":396,"children":398},{"className":397},[],[399],{"type":14,"value":400},"docker image ls",{"type":14,"value":402}," looks different.",{"type":14,"value":404}," What used to be ",{"type":9,"tag":46,"props":406,"children":408},{"className":407},[],[409],{"type":14,"value":410},"--tree",{"type":14,"value":412}," is the default view, and untagged images are no longer listed unless you pass ",{"type":9,"tag":46,"props":414,"children":416},{"className":415},[],[417],{"type":14,"value":418},"--all",{"type":14,"value":420},".",{"type":9,"tag":355,"props":422,"children":423},{},[424,429],{"type":9,"tag":89,"props":425,"children":426},{},[427],{"type":14,"value":428},"Attestations and SBOMs are first-class",{"type":14,"value":430},", which the supply-chain lessons in the Advanced course depend on.",{"type":9,"tag":10,"props":432,"children":433},{},[434,436,442,444,450],{"type":14,"value":435},"An existing installation that upgraded keeps its old store — the change is for fresh installs. ",{"type":9,"tag":46,"props":437,"children":439},{"className":438},[],[440],{"type":14,"value":441},"docker info",{"type":14,"value":443}," tells you which you have, under the storage driver line. And one carve-out worth knowing: daemons using ",{"type":9,"tag":46,"props":445,"children":447},{"className":446},[],[448],{"type":14,"value":449},"userns-remap",{"type":14,"value":451}," do not get the containerd store, because of an unresolved interaction between the two.",{"data":453,"body":454},{},{"type":6,"children":455},[456,462],{"type":9,"tag":34,"props":457,"children":459},{"id":458},"check-what-you-have",[460],{"type":14,"value":461},"Check what you have",{"type":9,"tag":10,"props":463,"children":464},{},[465],{"type":14,"value":466},"Everything in this course is written against specific versions, listed on the course page. Confirm yours before you start wondering why a flag does not exist:",{"data":468,"body":469},{},{"type":6,"children":470},[471,475],{"type":9,"tag":186,"props":472,"children":474},{":lines":473},"[{\"cmd\":\"docker version\",\"out\":\"Client: Docker Engine - Community\\n Version:    29.7.2\\nServer: Docker Engine - Community\\n Engine Version: 29.7.2\\n containerd Version: 2.2.2\\n runc Version: 1.3.4\"},{\"cmd\":\"docker compose version\",\"out\":\"Docker Compose version v5.5.0\"},{\"cmd\":\"docker buildx version\",\"out\":\"github.com/docker/buildx v0.36.1\"}]",[],{"type":9,"tag":10,"props":476,"children":477},{},[478,480,486,488,494],{"type":14,"value":479},"Note ",{"type":9,"tag":46,"props":481,"children":483},{"className":482},[],[484],{"type":14,"value":485},"docker compose",{"type":14,"value":487},", two words. ",{"type":9,"tag":46,"props":489,"children":491},{"className":490},[],[492],{"type":14,"value":493},"docker-compose",{"type":14,"value":495}," with a hyphen was the original Python implementation; it reached end of life in July 2023 and is not what you want. If a tutorial you are reading uses the hyphen, it predates a great deal of what this course covers — which is a useful signal in its own right.",{"data":497,"body":498},{},{"type":6,"children":499},[500,508],{"type":9,"tag":501,"props":502,"children":507},"fill-blank",{":answer":503,"hint":504,"placeholder":505,"prompt":506},"[\"docker ps\",\"docker container ls\",\"docker container list\",\"docker ps -a\"]","Two words. The short form is borrowed from a Unix command you already know.","docker ...","Show the currently running containers.",[],{"type":9,"tag":10,"props":509,"children":510},{},[511],{"type":14,"value":512},"Next up: running containers — the flags that make up 90% of what anyone types at a Docker prompt.",1787908866661]