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
dockerofficial documentationdocker composeofficial documentation- The
docker-composetool has been deprecated in favor of the newerdocker composecommand (notice the dash has been removed)
Docker tends to be easier to use when you have a docker-compose.yaml file and use the docker compose command to create and manage containers and their volumes.
docker compose up -dfollows instructions in docker-compose.yaml 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-dmakes the containers run in detached mode, i.e. they run in the background.docker compose logs -ftto see the live Docker logs. Note that some apps have logs of their own that may be accessible somewhere else.docker compose up -d --buildto rebuild images and to create and run the containers.docker compose up -d --pull=alwaysto redownload images from Docker Hub and to create and run the containers.docker compose psto list all containers that have not been stopped and see their statuses.docker ps -ato list all containers and see their statuses.docker image lsordocker imagesto list all images.docker volume lsto list all volumes.docker compose exec containerName /bin/bashto start an interactive Bash TTY inside a running container.docker compose exec containerName shto start an interactive shell TTY inside a running container.docker compose pauseto pause the containers.docker compose unpauseto unpause paused containers.docker compose stopto stop the containers (this clears their memory).docker compose startto start stopped containers.docker compose downto stop and delete the containers. Volumes persist.docker compose rmto delete stopped containers. Volumes persist.docker volume rm volumeNameto delete a volume.docker image rm imageNameto delete an image.docker container pruneto delete containers that failed.docker image pruneto delete unused images.docker build -t imageName .to build a new image in the current directory.docker run -it imageNameto create and run a container interactively.docker run -pd 12345:4000 --restart unless-stopped --name containerName imageNameto create and run a new container from an image, exposing port12345with internal app port4000.
pushing images to Docker Hub
- Make sure the Docker engine is running, such as by opening Docker Desktop.
docker login -u userNameand then enter an access token in place of a password.docker compose builddocker tag appName userName/appNamedocker push userName/appNamedocker tag userName/appName userName/appName:versionStringdocker 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.