Docker is a tool that makes running software easier by creating a container, which is like a little virtual computer with a more predictable configuration than most computers. Containers are very portable, by which I mean they can be created in and run in any operating system that can run Docker. For example, a container could run Linux within it, and the container itself could run on Mac, Windows, and Linux. They’re not the same as virtual machines though; containers are more lightweight and easier to automate.
Using Docker can significantly simplify the setup and deployment for software. The highlighted parts of the image below show the setup instructions for a Discord bot I made before and after configuring it to run in Docker.
The old way took a few hours every time I had to set up the bot. The new way takes only a few minutes after the first setup.
If you’re familiar with virtual environments, such as the ones commonly used by the Python community, think of Docker like a big virtual environment that works for any programming language.
how to get started with Docker
There are already many guides and tutorials I’ll let you find. For me, it was helpful to watch multiple videos about the basics of what Docker does.
Docker commands
docker
official documentationdocker compose
official documentation- The
docker-compose
tool has been deprecated in favor of the newerdocker compose
command.
Docker tends to be easier to use when you have a docker-compose.yml file and use the docker compose
command to create and manage containers and their volumes.
docker compose up -d
follows instructions in docker-compose.yml to build and run the app. Images may be built and/or downloaded from Docker Hub if needed before containers are created from the images. The-d
makes the containers run in detached mode, i.e. they run in the background.docker compose logs -ft
to see the live Docker logs. Note that some apps have logs of their own that may be accessible somewhere else.docker compose up -d --build
to rebuild images and to create and run the containers.docker compose up -d --pull=always
to redownload images from Docker Hub and to create and run the containers.docker compose ps
to list all containers that have not been stopped and see their statuses.docker ps -a
to list all containers and see their statuses.docker image ls
ordocker images
to list all images.docker volume ls
to list all volumes.docker compose exec containerName /bin/bash
to start an interactive Bash TTY inside a running container.docker compose exec containerName sh
to start an interactive shell TTY inside a running container.docker compose pause
to pause the containers.docker compose unpause
to unpause paused containers.docker compose stop
to stop the containers (this clears their memory).docker compose start
to start stopped containers.docker compose down
to stop and delete the containers. Volumes persist.docker compose rm
to delete stopped containers. Volumes persist.docker volume rm volumeName
to delete a volume.docker image rm imageName
to delete an image.docker container prune
to delete containers that failed.docker image prune
to delete unused images.docker build -t imageName .
to build a new image in the current directory.docker run -it imageName
to create and run a container interactively.docker run -pd 12345:4000 --restart unless-stopped --name containerName imageName
to create and run a new container from an image, exposing port12345
with internal app port4000
.
pushing images to Docker Hub
- Make sure the Docker engine is running, such as by opening Docker Desktop.
docker login -u userName
and then enter an access token in place of a password.docker compose build
docker tag appName userName/appName
docker push userName/appName
docker tag userName/appName userName/appName:versionString
docker push userName/appName:versionString
docker tag
and docker push
are used twice because not specifying a tag uses the default tag value latest
.
More details can be found in Publish your image by Docker.
security
Containers, and even virtual machines for that matter, are not necessarily secure enough to safely run arbitrary code within. Sandbox escapes are possible. Online code-running services like tio.run appear to usually use Security-Enhanced Linux (SELinux).
When running Docker on a Linux machine that is using UFW (Uncomplicated Firewall), Docker may bypass the firewall and create a security vulnerability. See How to fix the Docker and UFW security flaw (2018) for details. Although that page might be outdated, apparently Podman is generally more secure than Docker.