How to Set Up a Docker Container
Tags: docker, containers, beginners, tutorial
Published: 2024-03-13 12:11:17

[Docker](https://www.docker.com/) is a tool that makes it easier for developers to create, deploy, and run applications using containers. Containers package your application code with all its dependencies. So, the application can run smoothly across different computing environments.

Think of a container as a lightweight, self-sufficient box that carries everything your application needs to operate. 

Unlike virtual machines (VMs), which emulate an entire operating system, containers share the host system’s kernel. This makes them far more efficient in terms of resource use. 

With Docker, you can run more applications on a single server and start them much faster than you could with VMs. Also, Docker guarantees consistency –– a container that works on your laptop will work the same way in the cloud.

In this tutorial, you’ll learn everything you need to set up a Docker container. 

## Prerequisites

To follow this tutorial, the first step is installing Docker on your machine. Here’s what you need to know:

* **Operating System Support**: Docker works on the following:
    
    * macOS
        
    * Windows
        
    * Various Linux distros (Ubuntu, Debian, CentOS, etc.)
        
* **Specific Installation Instructions**: The installation process differs depending on your OS. You can find the latest instructions for your specific OS on the [official documentation](https://docs.docker.com/get-docker/) site.
    

Regardless of your operating system, make sure your computer meets the general system requirements for running Docker. You can usually find these requirements listed on the installation page for your OS in the Docker documentation.

## Key Docker Concepts

Before you go hands-on into using Docker, let’s get familiar with the building blocks of this technology. Here’s a quick overview of the essential elements:

### Images

Docker images are like the blueprints for your applications. They contain everything needed to create a functional container:

* The operating system
    
* Your application code
    
* Necessary libraries
    
* Any special settings
    

You can find ready-made images for many popular tools on [Docker Hub](https://hub.docker.com/) or create your own custom images.

### Containers

Containers are running instances of your images. Think of them as lightweight, self-contained environments where your application lives. You can run multiple containers from the same image simultaneously, and each container operates independently.

### Dockerfile

A Dockerfile is a special text file that contains a list of instructions on how to build a custom Docker image. It’s your recipe for crafting an image tailored to your specific application. Using a Dockerfile, you can define everything from starting the operating system to the exact steps needed to install and configure your software.

## Pulling and Running Your First Container

One of the easiest ways to get a feel for Docker is to pull a pre-built image and run a container based on it. Let’s use [Nginx](https://www.nginx.com/), a popular web server, as our example:

### Step 1: Pull the Image

The general syntax for pulling a Docker image is:

```bash
$ docker pull <image>:<image_tag>
```

Where:

* `docker pull`: core command to download a Docker image from a repository
    
* `<image>`: name of the image you want to pull. For example, `nginx` or `ubuntu`
    
* `:<image_tag>`: an optional tag that specifies a particular version or variant of the image. Here are some common tags:
    
    * `latest`: the most recently updated version of the image (this is the default if you don’t specify a tag
        
    * **Specific version numbers**: for example, `1.23.1`, to get a precise version**
        
    * **Other tags**: some images might have tags indicating their purpose like `alpine` (a small Linux distro) `-slim` (a more minimal version of an image).
        

For example:

```bash
$ docker pull nginx:latest

latest: Pulling from library/nginx
f546e941f15b: Pull complete
2d258780861a: Pull complete
a7d6e9feb830: Pull complete
42e0f9421c7a: Pull complete
14a95f763a2f: Pull complete
164c21b63fde: Pull complete
5b452a5fd809: Pull complete
Digest: sha256:c26ae7472d624ba1fafd296e73cecc4f93f853088e6a9c13c0d52f6ca5865107
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview nginx:latest
```

The above command downloads the latest version of the Nginx image from Docker Hub. The Hub is a vast public repository where you can find images for many popular software, databases, and tools.

Images often have different tags, like `latest`, or a specific version number (e.g., `nginx:1.23.1`). Tags help you choose the most suitable version for your needs.

While using `docker pull`, you’ll see output indicating multiple layers being downloaded. Images are built in layers, promoting efficiency. Each layer represents a change in the image’s filesystem. This layered approach means any updates often download just the changed layers, not the entire image.

### Step 2: Run the Container

Here’s the general syntax for running a Docker container:

```bash
$ docker run <image_name>
```

Below is a breakdown of the syntax:

* `docker run`: command to start a new container based on a specific image
    
* `<image_name>`: mandatory name of the image from which you want to create the container. If the image isn’t found locally, Docker will try to pull it from a registry (usually Docker Hub).
    

Furthermore, the `docker run` command can be used with a variety of additional options like `-d`, `-p`, etc.) to customize the container’s behavior.

For example:

```bash
$ docker run -d -p 8080:80 nginx
```

Let’s break the command down:

* `-d`: runs the container in detached mode (it’ll run in the background)
    
* `-p 8080:80`: maps port `8080` of your host machine to port `80` inside the container
    

Nginx, by default, listens on port `80` for web requests. This mapping allows you to interact with the webserver from your machine as if it were directly on your system.

### Step 3: Test it Out

After implementing `docker run`, the next step is to check if your Nginx server is functional. Open a browser and go to: [`http://localhost:8080`](http://localhost:8080). You should see the Nginx welcome page.

Congratulations! You’ve successfully run your first Docker container.

## Managing Docker Containers

Effective container management is crucial as you start using Docker more frequently. Here, we’ll explore some essential commands to help you view, stop, remove, and keep track of your running containers and images.

### 1\. Listing Your Running Containers: `docker ps`

Let’s begin by understanding what containers are currently running on your system. The `docker ps` command provides a convenient way to list them.

Here’s the basic syntax:

```bash
$ docker ps [OPTIONS]
```

Where:

* `docker ps`: is the base command to list containers
    
* You can optionally use flags (denoted by `[OPTIONS]`) to customize the output. A common flag is `-a` which shows all containers (including stopped ones)
    

For example:

```bash
$ docker ps

CONTAINER ID   IMAGE        COMMAND                  CREATED        STATUS       PORTS         NAMES
e34b2345f7bd  nginx        "nginx -g 'daemon off;'"   2 hours ago   Up 2 hours   0.0.0.0:8080->80/tcp  my_nginx_container
```

This output shows a single running container named `my_nginx_container` based on the `nginx` image. It’s been running for 2 hours and has port `80` mapped to port `8080` on the host machine.

### 2\. Stopping Running Containers: `docker stop`

When you need to halt a running container, the `docker stop` command is your friend. Let’s take a look at the syntax:

```bash
$ docker stop [OPTIONS] CONTAINER [CONTAINER...] 
```

Where:

* `docker stop`: base command to stop containers
    
* You must provide one or more container IDs or names (found with `docker ps`)
    

For example:

```bash
$ docker stop e34b2345f7bd  # Using the container ID
$ docker stop my_nginx_container  # Using the container name
```

Docker attempts a graceful shutdown by sending a signal to the container’s main process. If the process ignores it, Docker resorts to a forceful termination after a timeout.

### 3\. Removing Stopped Containers: `docker rm`

Stopped containers still consume disk space. The `docker rm` command allows you to clean these up. Take a look at the basic syntax below:

```bash
$ docker rm [OPTIONS] CONTAINER [CONTAINER...]
```

Where:

* `docker rm`: base command to remove stopped containers
    
* You must provide one or more container IDs or names
    

For example:

```bash
$ docker rm e34b2345f7bd 58df8a2168eb  # Removing multiple containers by ID
```

Removing containers is permanent. If you think you might need a stopped container, don’t remove it.

### 4\. Listing Your Images: `docker images`

It’s important to track the images stored on your system. The `docker images` command provides a snapshot of those images. Below is the basic syntax of the command:

```bash
$ docker images [OPTIONS] [REPOSITORY[:TAG]] 
```

Where:

* `docker images`: base command to list images
    
* It optionally accepts `REPOSITORY[:TAG]` to filter the list to images with a specific name and tag combination
    

For example:

```bash
$ docker images

REPOSITORY        TAG       IMAGE ID       CREATED        SIZE
nginx             latest    760b7cbba31e   3 weeks ago    192MB
ubuntu            latest    a50ab9f16797   3 weeks ago    69.2MB
warpdotdev/warp   0.0.23    499fa48260b8   3 months ago   8.08MB
```

The output indicates we have three Docker images stored locally. There’s Nginx (a web server), Ubuntu (a Linux distro), and a custom image named “warp”. You can use these images as the base to launch new containers whenever needed.

## Building Your Own Docker Image

While pre-built images for popular software are incredibly useful, the true power of Docker shines when you create images precisely tailored to your applications. This is where Dockerfile comes in.

### The Dockerfile: Your Image Blueprint

A Dockerfile is a text file containing a series of instructions that tell Docker how to assemble your image. Some of the common instructions you’ll use include:

* `FROM`: specifies the base image to start from (e.g., Ubuntu, Python, etc.)
    
* `WORKDIR`: sets the working directory for subsequent commands
    
* `COPY`: copies files or directories from your computer into the image
    
* `RUN`: executes commands to install dependencies or configure your application within the image
    
* `CMD`: defines the default command that runs when a container starts from this image
    

### The Build Process

Here’s a brief step-by-step process showing how to build your Docker image:

**1\. Create a Dockerfile:** Place a file named, `Dockerfile` in the root of your project directory.  
**2\. Build the image:** Use the `docker build` command. Below is the basic syntax:

```bash
$ docker build -t <image_name>:<optional_tag> .
```

Where:

* `-t`: tags your image with a name and optional tag for versioning
    
* `.`: specifies the location of your Dockerfile (\`.\` means the current directory)
    

### Example

Let’s imagine you have a basic `index.html` file. Here’s how you could build a Docker image to serve it using Nginx:

**Dockerfile**:

```bash
FROM nginx:alpine
WORKDIR /usr/share/nginx/html  
COPY index.html
RUN apk update && apk add curl
CMD ["nginx", "-g", "daemon off;"]
```

Let’s break down the content of the above file:

* `FROM nginx:alpine`: we’ll use a lightweight Alpine-based Nginx image as our starting point
    
* `WORKDIR`:  sets the working directory for any subsequent COPY, RUN, or CMD instructions. This keeps things organized within our image
    
* `COPY index.html: this copies our` index.html\` into the default Nginx web directory within the image
    
* `RUN`: executes a command during the image building process. Here, we are using Alpine's package manager (\`apk\`) to update the package lists and install the `curl` tool. This demonstrates how you can add necessary dependencies to your image.
    
* `CMD`: specifies the default command to execute when a container starts from this image. This ensures Nginx runs in the foreground, keeping the container alive.
    
* `"-g", "daemon off;"`: tells Nginx to run in the foreground, instead of the background.
    

Now, let’s build the image. Open your terminal, navigate to your project directory and run:

```bash
$ docker build -t my-first-image .
```

Where:

* `docker build`: the command to build images from Dockerfiles
    
* `-t my-first-image`: tags your image, giving it a name
    
* `.`: final dot tells Docker to use the current directory as the location of your Dockerfile
    

To test, let’s run a container from our newly built image:

```bash
$ docker run -d -p 8080:80 my-first-image
```

Open `http://localhost:8080` in your web browser to see your website!

## Conclusion

In this tutorial, we’ve covered the essentials of the exciting world of Docker such as:

* Understanding the difference between images and containers
    
* Using Docker Hub to find pre-built images
    
* Crafting your own custom images using Dockerfiles
    
* Managing containers with core Docker commands
    

This foundation now opens the door to even more powerful concepts. You can explore more advanced concepts such as container networking, streamlining the management of complex applications with [Docker Compose](https://docs.docker.com/compose/), and how to make your application data persistent using volumes.

---

*Thanks for reading! If you found this article helpful (which I bet you did 😉), got a question or spotted an error/typo... do well to leave your feedback in the comment section.*

*And if you’re feeling generous (which I hope you are 🙂) or want to encourage me, you can put a smile on my face by getting me a cup (or thousand cups) of coffee below. :)*

* [***Buy Me a Coffee***](https://www.buymeacoffee.com/emminex23)
    

*Also, feel free to connect with me via* [***LinkedIn***](https://www.linkedin.com/in/emmanueloyibo2394/)*.*