Learning about Docker
Tags: docker
Published: 2023-11-07 09:09:58

Today I spent some time learning about Docker, and I wanna try to solidify that learning by recapping it for myself here!


I've been meaning to learn about Docker for a long time, but why did I finally look into it today? Well, as you can see from my [previous post on Codedex](https://www.codedex.io/community/post/j7vpRbgBRKrtFPZpOFjF), I've been learning about web servers lately, and trying to set up different websites for my art stuff. Since yesterday I've been looking into building my own ecommerce storefront to sell my art from, and today I saw someone saying that the fastest way to install a certain ecommerce platform (Magento) was via Docker. So I figured, might as well finally get around to learning it! I'll also need it for some of the stuff I'm trying to do with my Raspberry Pi, I think.


So first, what's the point of Docker? It's a way to bundle up an application together with all of the system configuration required to run it. It makes it easier to move the app you're coding between environments--like from your local development environment to a deployment--without having to manually configure everything based on the details (like OS and architecture) of each machine. It lets you kind of ignore the particulars of what computer you're running the Docker container on, and guarantee that the system will be configured in a well-defined way. I think the reason that the one dude said Docker was the fastest way to run Magento is that the Docker image he was using includes all the dependencies Magento requires, along with all the configs needed for each of them, and so you can just install this one Docker image in a single step instead of having to go through the installation and setup of each dependency one by one and manually configure them all to talk to each other correctly. Somebody else *already did* the step of configuring them to talk to each other, and saved it to this Docker image.


By the way, a "Docker image" is a file that contains the source code that you want to run, and a "Docker container" is the live instance running a Docker image. 


Docker is a type of virtualization technology, but it's not the same as a virtual machine. A virtual machine encapsulates the entire operating system, including the kernel. But a Docker image only includes the "application layer" of the operating system, *not* the kernel. This makes Docker images way smaller files than the images(?) for virtual machines, and makes Docker containers much faster to create. A Docker container actually uses the kernel of the host machine that it's running on! 


(Interesting sidenote: This means that Linux-based Docker images should only be able to run on Linux machines! How did they deal with this to allow devs to work with Docker containers from Windows or Mac computers? Well, the Docker Desktop software that you have to install to run Docker on Windows or Mac actually creates a Linux virtual machine to run your containers on top of!)


(Sidenote to the sidenote: There's a Docker Desktop for Linux too, and these days Docker encourages you to install via Docker Desktop even on Linux, but apparently it is VERY picky in its system requirements, and it isn't compatible with the XFCE desktop environment that I use! So after way too much troubleshooting, I had to just uninstall Docker Desktop and try again with the old school Docker Engine packages.)


To start working with Docker containers, you need to install the Docker software on the computer you're working from--and if you want to deploy your app via Docker, then you also need to install Docker on the deployment environment. Like in my case, if I want to use Docker for my Magento store, I'll need to install Docker itself on the server that my store will be hosted on first, before I can create the Magento container there.


Once you have Docker installed, you just need to start the service/daemon, and then you can start running Docker commands from the terminal! There's a bunch of commands you can use to download Docker images, and to start and stop and manage containers, but I'm not going to bother listing out the details because it's easy enough to look up the commands when needed. Here's a nice [guide](https://christitus.com/docker-guide/).


The workflow is like this: 

-    Start the Docker service (you can set this up to happen automatically)
-    Download (pull) the Docker image that contains the app you want to run
-    Create and start a container from that image
-    Access the container's app through a certain port on your computer
-    Stop the container when you're done


If you want to actually interact with the app that's running inside the container, then you need to do what's called binding a port. This is an argument you pass in while creating the container that tells your computer that, if you try to visit a certain port, direct that request to the port inside of this container instead. For example, if you're running a web server in a Docker container, that would normally be available over HTTP on port 80 of the server--but in this case, that refers to port 80 *inside* the virtual system. Port binding means telling your real, physical computer "hey, when I look at *your* port 80, I want you to pull up this Docker container and show me what's on *its* port 80." It doesn't even need to be the same number! That's really useful for if you have like, 3 containers on your computer that are all running web servers and all expect to be on port 80--they can all be on their own internal port 80 at the same time, meanwhile they're each bound to a different number of external port, so they're all available at the same time. 

(By the way, I don't really understand ports or networking, so my language might not be quite right... please correct any mistakes I made!)


Lastly, all of that was assuming you're working with an image that contains somebody else's code. But what about when you want to actually put your own code into a Docker image? You write what's called a Dockerfile in your project directory, and use that (with a terminal command) to build your image! Then you can use it just like any other image. If you're like me, maybe you've been seeing these files called "Dockerfile" in Git repos for a long time and wondering what they're for, right? It feels so good to finally know what it does, haha. If you look inside one of these, it's a pretty straightforward text file. It's just a bunch of instructions that tell Docker how to make your image. Interestingly, it always needs to begin by calling out a pre-existing Docker image that will be used as the basis of your image! For instance, this might be an image that just contains the basic operating system files, or it might be an image pre-configured with something like Python or Node. (It does make me very curious about how those "starter" operating system images get created though!) Then, you add instructions to copy your local files into the Docker image, and commands to run to set up the environment, like `npm install`. Then there's always one last command that tells Docker how to start your app itself, like by executing a certain file.


And I think that's about everything I learned today! Phew! Sure looks like a lot now that I've written it all out... but I haven't even started experimenting with *using* Docker myself yet. All I did was install the software and run the hello-world Docker container to test my installation. Looking forward to trying out that Magento Docker image that I was reading about, though!

_[Cross-posted to Codedex.io Community](https://www.codedex.io/community/post/ezakJ7X21ZOKSYjIipJ7)_