Log In

Sharing Data Between the Docker Container and the Host

Sharing Data Between the Docker Container and the Host
03.05.2024
Reading time: 6 min
Hostman Team
Technical writer

One of the reasons Docker is so popular is that it allows containerization without installing additional dependencies on your local machine. Docker uses virtualization technology that creates an isolated environment for running applications.

The Docker engine assigns host resources to an isolated application in a container. Once such an application is containerized, its virtualized data is isolated from the host, causing all application data to remain in the container.

However, the application often needs to share data between the Docker container and the host computer.

By default, all files created in a container are stored in it. When the container stops, data is lost. Docker has volumes that you can use to store data on the host system so that it is not lost even after the container is stopped.

In this article, we will show you how to organize data sharing so that your app can access the host data from a Docker container.

Prerequisites

To follow this guide, you will need:

  • A cloud server running a Linux-based OS (Ubuntu, Debian, CentOS etc) with Docker installed. You can deploy your Linux server on Hostman and even install Docker with one click.

  • A root user or a non-root user with sudo privileges.

Preparation

To demonstrate data sharing between the host and the container, we will use Nginx and HTML pages.

Let's pull the Nginx image from the Docker repository using the following command:

docker pull nginx

You can check whether the image was loaded successfully using the docker image ls command. The terminal should display a list of downloaded images:

Image2

In Docker, a volume is a mechanism for storing and managing data used inside containers. You can think of a volume as a separate file system that can be attached to one or more containers.

The main benefit of using volumes in Docker is that they allow you to persist data between container runs and even between deleting and creating new containers. Volumes can also be used to share data between containers, for example, when multiple containers need to access a common file system.

Docker provides many tools for working with volumes, including commands for creating, deleting, mounting, and unmounting volumes. It also allows you to specify which volume should be used in the container when it starts.

In Docker, to access the host from the container, you can use an existing directory in the host file system (bind mount) or a new volume entity. We will look at both methods.

Bind mount

By default, applications in Docker containers are stateless. This means the application does not leave any data after its operation. Therefore, Docker provides various methods for storing data. In this section, we will talk about bind mount.

Bind mount implements the following operating principle: the data file is stored on the host and opened inside the container. Because the data is stored on the host, it is not lost when the container shuts down.

We will use an HTML page as the data file.

To use bind mount, follow these steps:

Step 1. Create a directory with the HTML file:

mkdir -p /tmp/nginx/html

Step 2. Build and launch the container with the Nginx image using the docker run command:

docker run -t -d -P -v /tmp/nginx/html:/usr/share/nginx/html --name nginxcont nginx:latest

The parameters to this command will launch a container named nginxcont with the Nginx image and pass the HTML directory to the container:

  • -t will allocate a pseudo-TTY for interactive interaction with the container;

  • -d will start the container in the background;

  • -P will bind the container to a random port;

  • -v allows us to mount the host folder into a container in Docker.

After executing the command, check the running containers:

docker container ls

Image3

Step 3. Find out the IP address.

To find out the IP address of the Docker host, enter the command below:

hostname -I

To find the port number, check the PORTS column in the Step 2 or simply run docker container ls.

Go to your browser and enter the following URL:

http://<ip_address>:<port>

Since we don't have an HTML file in the directory, the content should be something like this:

Image5

Step 4: Testing

In the /tmp/nginx/html directory, create a file index.html:

nano /tmp/nginx/html/index.html

And add the following lines of code to it:

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
   <title>Checking the functionality of bind mount</title>
</head>
<body>
   <h1>This HTML file is taken from the host machine</h1>
   <p>
     If you see this page, then everything is working. The file was taken from the /tmp/nginx/html directory and transferred to the container via the console.
   </p>
   <p>
   </p>
   <p><em>Hostman Tutorials</em></p>
</body>
</html>

To save the file press Ctrl+X and then Y.

Once the file is created, refresh your browser tab and you will see the new content:

Image6

If you edit the file, you will see the new changes after refreshing the page. 

Now you know how to share files from your host machine to a Docker container using bind mount.

If you see the error "localhost didn’t send any data", check:

  • the directory in which the container is running;

  • whether the container is running;

  • is the port was assigned to another application.

Volume

To use volumes for data sharing between a host and a container, follow these steps.

Step 1: Create a volume.

You can create a new volume with this command:

docker volume create simplevol

Where simplevol is the name of the new volume. 

Now list all volumes:

docker volume ls

We will see:

Image4

Step 2: Start a Docker container.

Launch a new container (nginxcont1 in our example) with an NGINX image:

docker run -t -d -P -v simplevol:/usr/share/nginx/html --name nginxcont1 nginx:latest

The volume on localhost is mapped to a directory inside the container from which NGINX takes the HTML.

To check the state of the container, run this command:

docker container ls

Note the port number in the PORTS column too, we will need it in the next step.

Image3

Step 3: Find out the IP address.

To get the host's IP address, run:

ifconfig

The inet parameter will show your IP address. In our case, it is 172.19.0.1.

Image1

Now, go to http://<ip_address>:<port>, specifying your IP address and the port number from Step 2.

You should be greeted with the standard NGINX page.

Image7

Step 4. Testing.

Copy the index.html file from the Docker container to the host computer using the following command:

docker cp nginxcont1:/usr/share/nginx/html/index.html index.html

Open the file using an editor, update it as follows and save:

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
   <title>Checking the performance of volumes</title>
</head>
<body>
   <h1>This HTML code runs in a container with an NGINX image</h1>
   <p>
     If you see this page, everything is working. The index.html file is stored in the volume and shared with the container via the console.
   </p>
   <p>
   </p>
   <p><em>Hostman Tutorials</em></p>
</body>
</html>

You can copy the edited file back from your computer to the Docker container by running this command:

docker cp index.html nginxcont1:/usr/share/nginx/html

If you refresh the previously opened tab, the content will update:

Image8

Conclusion

In this article, we looked at two ways to share data between the host and the container. If you use Docker volumes, you can also use them to share data between different environments running in the Docker environment.


Share