learning about Docker
Jan. 29th, 2022 07:42 pmI've been meaning to teach myself about Docker since at least June of 2020, the last time I attended a technical conference (albeit online) and noticed that it was a common point of reference. Also, Dreamwidth has been using Docker in production since around that time. But I didn't manage to clear up the mental bandwidth to study it until this past week. I'm going to share my notes here, since I think it's a helpful thing to know about.
What is Docker? It's a software package that provides an isolated system environment for running applications. In practice, a Docker instance is not unlike a virtual machine, but with one key difference: you don't have to install and maintain a separate operating system. A Docker image is relatively lightweight and completely portable across different systems. Bonus: it doesn't cost anything to use unless you're a large company.
I found these resources particularly helpful:
1. Video: Learn Docker in 12 Minutes and its sequel, Docker Compose in 12 Minutes. I found these two to be the most accurate and accessible of the ones I viewed. There are many other similar videos online if you find those to be a bit too fast-paced, but the presentation quality varies widely.
2. Reading: The Docker Handbook is a free online book, presented as a single really long web page, that does an excellent job of describing how to use Docker.
3. Tutorial: Upon installing Docker, the software will instruct you to run its "getting-started" image, which contains some basic lessons and exercises. You can also view the same material on the Docker website.
All three of those explain how to get Docker on your machine, so I won't go into that here. Instead, here's a data dump from the notes I took when I was clarifying the basic concepts in my head.
The most important concept to understand, I think, is the difference between a Docker image and a Docker container. I saw multiple presentations where images and containers were referred to interchangeably, but the first video I linked above makes the distinction very clear. You build a Dockerfile to get an install image; you run the image to get a container instance. You can think of a Docker image as a software package, and a Docker container as an actively running copy of that software.
What is a Dockerfile? It's a straightforward, usually brief, description of what you want your image to contain: base operating system, software packages, config files, etc. There are lots of preconfigured base images stored in a central repository so that you don't have to do a ton of work. Again, the resources above have lots of examples of these.
Generally speaking, you want to design each Docker image to encapsulate a single process or service. You can run as many simultaneous containers as you want, since they're so lightweight, but each container only stays running for the lifetime of the process it encapsulates. When that process exits, the container will stop. Any changes you make within a container while it's running will only affect that container; they won't affect the image that you used to run the container. The only way to change the image is to change its Dockerfile and rebuild it.
Each container is completely isolated from its host machine and from other containers on the same host. If they need to communicate with each other, you will need to manually specify at runtime any shared folders or exposed network ports. If you end up with several linked containers that regularly run as a group, you can use Docker Compose to codify their relationships and bring them all up or down with a single command.
Syntax cheat sheet:
- docker build [--tag <image-name>] <directory> to build an image (the named directory should contain a file named "Dockerfile") - if you don't specify an image name, one will be randomly assigned
- docker run [--name <container-name>] <image-name> to run a container based on the given image - if you don't specify a container name, one will be randomly assigned
- docker exec <container-name> <command> to run a given command on an active container
- docker run --rm will delete the container when it exits
- docker run -d will run the container detached from the terminal (as a background process)
- docker run -it will run the container as an interactive terminal
- docker run -p <local port>:<container port> will do port forwarding
- docker run -v <local folder>:<container mount point> will let the container access the named folder on the host for data that the host can also change while the container is running, and that will persist after the container is gone
I've only done the tutorial so far; my next goal, obviously, is to figure out how to use Docker to run a local DW development environment. The files in https://github.com/dreamwidth/dw-free/tree/master/etc/docker should provide a good starting point.
What is Docker? It's a software package that provides an isolated system environment for running applications. In practice, a Docker instance is not unlike a virtual machine, but with one key difference: you don't have to install and maintain a separate operating system. A Docker image is relatively lightweight and completely portable across different systems. Bonus: it doesn't cost anything to use unless you're a large company.
I found these resources particularly helpful:
1. Video: Learn Docker in 12 Minutes and its sequel, Docker Compose in 12 Minutes. I found these two to be the most accurate and accessible of the ones I viewed. There are many other similar videos online if you find those to be a bit too fast-paced, but the presentation quality varies widely.
2. Reading: The Docker Handbook is a free online book, presented as a single really long web page, that does an excellent job of describing how to use Docker.
3. Tutorial: Upon installing Docker, the software will instruct you to run its "getting-started" image, which contains some basic lessons and exercises. You can also view the same material on the Docker website.
All three of those explain how to get Docker on your machine, so I won't go into that here. Instead, here's a data dump from the notes I took when I was clarifying the basic concepts in my head.
The most important concept to understand, I think, is the difference between a Docker image and a Docker container. I saw multiple presentations where images and containers were referred to interchangeably, but the first video I linked above makes the distinction very clear. You build a Dockerfile to get an install image; you run the image to get a container instance. You can think of a Docker image as a software package, and a Docker container as an actively running copy of that software.
What is a Dockerfile? It's a straightforward, usually brief, description of what you want your image to contain: base operating system, software packages, config files, etc. There are lots of preconfigured base images stored in a central repository so that you don't have to do a ton of work. Again, the resources above have lots of examples of these.
Generally speaking, you want to design each Docker image to encapsulate a single process or service. You can run as many simultaneous containers as you want, since they're so lightweight, but each container only stays running for the lifetime of the process it encapsulates. When that process exits, the container will stop. Any changes you make within a container while it's running will only affect that container; they won't affect the image that you used to run the container. The only way to change the image is to change its Dockerfile and rebuild it.
Each container is completely isolated from its host machine and from other containers on the same host. If they need to communicate with each other, you will need to manually specify at runtime any shared folders or exposed network ports. If you end up with several linked containers that regularly run as a group, you can use Docker Compose to codify their relationships and bring them all up or down with a single command.
Syntax cheat sheet:
- docker build [--tag <image-name>] <directory> to build an image (the named directory should contain a file named "Dockerfile") - if you don't specify an image name, one will be randomly assigned
- docker run [--name <container-name>] <image-name> to run a container based on the given image - if you don't specify a container name, one will be randomly assigned
- docker exec <container-name> <command> to run a given command on an active container
- docker run --rm will delete the container when it exits
- docker run -d will run the container detached from the terminal (as a background process)
- docker run -it will run the container as an interactive terminal
- docker run -p <local port>:<container port> will do port forwarding
- docker run -v <local folder>:<container mount point> will let the container access the named folder on the host for data that the host can also change while the container is running, and that will persist after the container is gone
I've only done the tutorial so far; my next goal, obviously, is to figure out how to use Docker to run a local DW development environment. The files in https://github.com/dreamwidth/dw-free/tree/master/etc/docker should provide a good starting point.