Introduction to Docker Containers

Joshua Hall

In this article, we’re going to be exploring in depth how to work with Docker containers from the command line. If you’re new to Docker I recommend checking out this introduction to get started with some of the concepts we’ll be using.

Creating a Container

To create a new container we’re going to need a base image to run or do anything inside of our container, for that we’ll start with the NGINX image from Dockerhub, so we can play with starting a basic server. The command syntax is pretty straight forward, and generally follows the form of docker [type] [command] [properties/flags].

$ docker container create nginx

This checks your image cache before sending a request to Dockerhub for the latest NGINX image. If you were to run this again it’ll be much faster since it won’t need to be re-downloaded.

Our container’s created but not running, we can see all of our containers by using ls to list them, and the -a flag to search for all, active and inactive. You could also use the older format docker ps -a.

$ docker container ls -a

You should see a table with information about your new NGINX container, most importantly the CONTAINER ID and NAMES columns. We’ll use any of those two to start our new container.

You don't need to use the full ID, just enough to make sure it's unique, 3 or 4 characters is fine.

$ docker container start [Container_name/ID]

Listing your containers without the -a flag should show your new active server. The problem now is that there’s no way to access it from the outside. We can establish a port with the -p flag (short for publish) and pass it the port we want it available on and port the server is located on, which for NGINX is port 80 by default. -p 4000:80 should let us access it on port 4000.

Instead of working with IDs or the auto generated name, let’s give it a name of our own with the --name flag. Using the run command is a nice shortcut for running create and start simultaneously.

$ docker container run -p 4000:80 --name new_server nginx 

Now you can visit your new server on either localhost:4000, if you’re on mac, or with the IP that Docker gives you similar to instead of localhost, if you’re on windows.

NGINX server page

Stopping and Removing Containers

Now you have two running NGINX containers and only need the latest. We can stop it with the stop command then remove it with rm.

$ docker container stop [Container_name/ID]
$ docker container rm [Container_name/ID]

Docker doesn’t want you to be able to stop and delete containers at the same time, since that could be done by accident, but you can force it if you need to with the -f flag.

You can list more than one container at a time.

$ docker container rm [Container_name/ID] -f

Looking Inside Containers

Let’s get inside of a container and see what we’re really working with. There are two flags that will let us do this, the -i flag will let us interact with our container and -t to format the log output in a more useful way. It’s pretty common to just chain them together.

Alpine is a Linux based operating system that is very basic and perfect for a minimalist base image. We can use the sh command to be immediately moved into a shell terminal inside our container.

$ docker container run -it --name new_project alpine sh

Now this should work just like any other shell terminal, run ls to see all the files and start exploring this mini OS cut off from the rest of our machine.



createCreates a new container
startRuns an existing container
runCreates then starts a new container
stopStops a running container
rmDeletes a stopped container
lsLogs all running containers
psLogs all running containers (deprecated)
shOpens a shell terminal


-a–allForces log of all output
-p–publishMaps a container to a port
-f–forceForces a command
-i Allows you to interact with a running container
-t Formats output to be more readable

Closing Thoughts

Working with single containers is pretty simple to get the hang of, but the complexity will only grow as you start working with multiple containers per project and try to manage the relationships between them. That’s why it’s essential to get comfortable with the basic operations now.

In future articles, we’ll look deeper into creating our own images and getting projects to work inside our little oasis.

  Tweet It

🕵 Search Results

🔎 Searching...