Why is everyone excited?

Docker is, simply put, a container. How is this at all exciting? Think about any time you set up a system, and how long you spend setting it up. No matter if it's a web server, a build environment or any other system service. Do you want to do that all over again when you move systems? What about updating your operating system under it, and having to deal with config file changes, and the other cruft that gets left behind, and causes problems over time? Not having to deal with any of this is why people like docker.

What docker is, and more importantly, what it's not.

Some people assume that docker is just another container like a virtual machine. While it is true that docker will spin up a minimal Linux environment, it does this every single time that the docker instance is started, and when stopped, it throws it all away. This seems like it would be a massive pain to update every single time you wanted to add new content to it, but this wasn't overlooked when Docker was designed.

Getting started with Docker

The getting started link for Docker is here so you can install it properly no matter what platform you are on. Once docker is up and running, feel free to come back. Otherwise, let's see what docker can do for you.

Basic example

Give this command a run in a terminal/command prompt, then navigate a web browser to http://127.0.0.1 and you should see a web browser running.

docker run -d -p 80:80 docker/getting-started

Lets break down what that command is doing. You docker is the basic command to directly control Docker. run tells it that you want to run something inside of docker. -d tells docker to run it in the background, as a daemon. -p 80:80 forwards the port 80 from your local machine, where docker is running on, to port 80 in the container. This is the standard HTTP web port that allows you to access that server. The url could have been typed http://127.0.0.1:80, but 80 is implied for HTTP, so it didn't need typed. docker/getting-started is the docker image that is running inside of the container, and that image starts the web server that you see when you load the web page.

Docker-compose

Typing commands can get very confusing, especially as things get more complex, so I would recommend learning docker-compose early. You may need to install it separately on your system. The same command as above would be saved as a file called docker-compose.yml and is yaml formatted as the filename implies.

---
version "2.3"
services:
    getting-started:
            image: docker/getting-started
            ports:
                80:80
                

Make it useful

Docker compose files can be brought up by running docker-compose up -d. The -d will run it in the background. If you omit this, you can see what's going on, and stop it with ctrl c like any normal command.

---
version: "3"  # Specifies the compose version

services:  # The list of services are below
    nginxBlog:  # The only service will be this blog, running on nginx
        image: nginx  # Runs on the nginx official image
        container_name: blog  # Sets the name of the container to keep track easier
        ports:
            - 80:80  # opens up port 80 to let you access the blog
        volumes:
            # Passes through /mnt/data/blog from the host to where nginx expects a web page to be
            - /mnt/data/blog:/usr/share/nginx/html  # passes through /mnt/data/blog from the host to where nginx expects 
        restart: unless-stopped  # Automatically restarts the service on restart of docker, or host reboot, ect

This is how this blog gets to you (partially). What happens if I start this docker container on another machine? I have to upload my blog to all of them and keep them in sync? Not at all. It just takes an edit to how docker has access to data.

---
version: "3"  # Specifies the compose version

services:  # The list of services are below
    nginxBlog:  # The only service will be this blog, running on nginx
        image: nginx  # Runs on the nginx official image
        container_name: blog  # Sets the name of the container to keep track easier
        ports:
            - 80:80  # opens up port 80 to let you access the blog
        volumes:
            # This time we will pass the volume from below through to the container.
            - blog:/usr/share/nginx/html  # passes through /mnt/data/blog from the host to where nginx expects 
        restart: unless-stopped  # Automatically restarts the service on restart of docker, or host reboot, ect
        
volumes:
    blog:
        driver: local
        driver_opts:
            type:nfs
            o: "addr=192.168.25.51"
            device: ":/mnt/data/blog"

This will let docker manage a mount though NFS (assuming it's available on that machine). This means that you can use use this file with any computer that has access to that NFS mount.

Docker swarm

Speaking of managing multiple computers with docker, why bother choose what goes where for things you don't care about what machine hosts it? Docker swarm has you covered. I'll link the getting started guide here as reference, but I'll highlight some of the things I was confused about going in, as well as some other benefits to running a swarm.

Short list of upsides

  • High reliability services. Can run multiple instances in case one is restarting/crashing/overloaded
  • Automatically can use any node that joins the swarm with little to no effort after joining
  • Can easily reboot machines for updates, and docker containers stay up, or automatically come back up on another machine

Questions I and others have/had


Q: How do I know what IP address to access?

A: Docker swarm includes a load balancer. You can access any machine in the swarm on the port you want, and it will serve it to you properly.


Q: What if I need something specific for the container?

A: Docker swarm includes concepts of tagging. You may want to separate things that need ARM or x86_64 CPU's. You may also tag a system as "low_ram" for things like a raspberry pi so a minecraft server doesn't decide to try to start there. Tags are arbitrary, so you can craft it to your needs.


Q: How do I update the container?

A: You don't think about it most of the time. The implied tag for containers is :latest, which will automatically pull down the latest version of the container every time it's restarted. If you lock a version, you know when to change the version tag, but docker does the rest for you.

Other uses for docker

Docker isn't limited to running services for servers. You can use it as a container to test applications without installing them on your system directly. This is also great for dev environments as there's no more "works on my system" bugs due to the nature of everything inside of the container always being the same on all systems. I'll link an article on how to do this with Rust, but it should translate to most projects well.

Conclusion

Docker is a great way to carry around services, build environments, and many other things that help you think less about the "how do I get there" and more about whatever your goal is. When I wanted to spin this blog up, I didn't care that I had to use a web server, or how it went together. I just started an nginx instance in docker, and I am done forever. Hopefully this has helped you see what's so great about docker. Feel free to reach out with questions, and I'll update the page with any common ones.