Learning Docker: My Tutorial Experience Part 1
I have been so excited to learn Docker. For so long, it's been a name floating around every tech space I've inhabited, but I haven't had the time to sit down and look into the details of what it is or how it works in a practical sense.
Today, I took the leap and downloaded Docker, so I could start plugging away at it. About a third of the way through the tutorial, I decided to write this post. Why? Because there were some parts I found confusing, and if I found them confusing then maybe someone else did, too. In terms of my starting knowledge, I've recently completed a course in full-stack web development using the MERN stack, and consider myself to be at an intermediate level with regards to web development generally, and a beginner with regards to backend/servers/DB/etc.
Below, I'll outline what I'm learning as I'm learning it, as well as any points that have held me up. Before I begin, I want to say how lovely it is to have a proper tutorial written for this technology. As someone who enjoys making tutorials for others, I am often frustrated with the writing quality of documentation, as it often feels designed to make things more confusing than necessary, even when I'm already well-versed in the technology at hand.
On the whole, the Docker tutorial has been a smooth experience, which is one reason why a few tweaks could make it even better.
What are containers?
Containers, as I understand them, are ways to take all parts of your project (frontend, backend, config, dependencies, etc.) and squish them together into one place: almost like a massive configuration file combined with a ZIP file. This means that anyone who wants to work on the code for that project doesn't have to run too much setup themselves, but can instead unpack a 'container image' to bring the entire project environment onto their own computer.
Early Problem: Setup
After installation (which required two restarts on Windows x64), Docker asked me to run a setup command in the terminal. Not thinking, I opened my VSCode terminal, created a new folder (called 'DockerSetup') and ran the command there. Unfortunately, what that meant is that I'd started it in the wrong place - what they had wanted was for me to start up the command prompt and just work in the default directory. I discovered this when I was informed that the port was already taken further into the step-through tutorial (which had been very easy thus far). I did some Googling and removed the Docker file I had put into the
DockerSetup folder, but then was told the image name already existed. I was stuck, so did what anyone in tech would do: I restarted the programme.
Unfortunately, this meant that I no longer had the step-by-step, on-screen tutorial to work from, which is a shame because I'd been enjoying it. Running the tutorial command again led me to the browser tutorial instead. My guess is that I would have been led there after initial setup anyway, but it was frustrating as a beginner to feel like I "missed out" on information which could be useful to me later (What do I know? I'm a beginner!).
I am so glad that the tutorial acknowledged how many steps this took originally. As I made the tutorial's text change (not to the recommended text but instead to an incredibly realistic rendering of a whale sound) I found myself thinking "Am I going to have to do this every time I change this app?". As the tutorial stated, we also lose any data we saved during the session.
Note: For any other beginners reading this, it's important to note that you don't need Docker to run your local environment. My understanding is that Docker will only be run once you're ready to 'pack it up and ship it out', so to speak. So even if updating is laborious, it is not something you have to run every time you change a line of code.
I'm going to write it here because someone might google "How to find your Docker ID" like I did...
"Docker ID" is just another term for "Username"
Why the Docker team decided not to put a little help icon or just call this "Docker Username" I have no idea. When I went to create a Docker Hub account and saw "Docker ID" I went Googling and looking through Docker Desktop settings trying to find what my ID was, thinking this was some specialised terminology or some device identification. Nope, it is literally just a username. Can we please just call it a username?
What is Docker Hub?
Ooooooh I like this a lot. Already it feels fantastically simple to use. In short, Docker Hub is basically a site where you can list and access different Docker container images. If you've used GitHub, then it is easy: Docker Hub is to container images, what GitHub is to Git repositories. It is also similar to how npm works with packages: you simply refer to the image you want to access, then whack out:
docker run -dp 3000:3000 user-name/container-name
BOOM! Everything is installed, just like that. Of course, you can change ports as well if you think 3000 is just, like, so passé.
Section: The Container's File System
I suspect that not enough beginners have given feedback here, because there are some basic problems with the construction of this section. On the whole, I did come away understanding that file changes weren't seen in different runtimes of the same container, however I already knew that based on the experience in the "Updating our App" section. In short, this section needs a rework to be more simple, and not to use un-introduced terminology.
Here are some things I didn't learn, but should have:
- What exactly is the 'scratch space' and what changes count as being part of it vs not?
- Why is there a "Seeing this in practice" section with an overcomplicated example, when we've already seen this in practice with the tutorial's own todo app? I suspect it's to try and answer the 'scratch space' question above: but to me it added nothing new and just seemed like an unnecessary side-step which didn't actually clarify what the 'scratch space' is.
- Let's talk about this paragraph. I re-read this paragraph maybe ten times.
I have so many questions:
- What is a "specific filesystem path" and is it the same/different to just a directory/file in our container?
- What is "mounted"? This question is actually answered three paragraphs later. Why are they using terminology they know we don't know, three paragraphs before they introduce it to us?
- What is the "host machine" in this case?
- "If we mount that same directory across container restarts, we'd see the same files." Well hang on, isn't that what we already did when we changed the text of our todo? We saw the file change, we didn't see the database updates. Again, this seems to be a miscommunication about what is constituted as part of the container image, and what is part of the 'scratch space'.
- "There are two main types of volumes": Why tell us this if you won't clarify what those two are?
- "We will work with named volumes": OK? Why introduce this piece of information here, when you don't even tell use what a named volume is until, again, three paragraphs later?
Running our named volume, I encounter an error: "port is already allocated". Of course, this is because I have been following this tutorial through and have not stopped/removed/etc anything. I go back into Docker Desktop and remove the new and old containers, then try again, and it works. However, this is not acknowledged anywhere in the tutorial itself, and I think that shows that this step was written in isolation from the rest of the tutorial.
The latter half of this section is the actually useful part, and we finally see the commands we need to persist data across multiple instances (?) of a container. As I understand it, this is the flow:
What is still unclear to me is how this would work in a larger context: clearly, this is on the same machine, so no big whoop. I could achieve the same thing by just, y'know, not deleting my container instance.
If I wanted a colleague or friend to see the same data/changes, would I be uploading my volume to Docker Hub? Or would I simply load up my container from the volume, and upload that container as it is to Docker Hub? This is the part that I'm still confused by at the end of this section.
UPDATE: After doing some snooping, it appears you cannot, in fact, push a volume to Docker Hub at all. So I am guessing its usage is designed for within a business' intranet? I'm a bit confused as to what the usage is now: maybe also for when you shut down your computer? What's the use case here?