Start from the NGINX container we created in a previous post
docker run -p 80:80 -d --name websrv nginx:latest
The problem we’re going to solve here is: how do we add a custom webpage for NGINX to display? The container’s filesystem is separate from the host’s.
Create a File in the Container
We can create the file directly in the container. Let’s start a shell in interactive mode in the container
docker exec -it websrv bash
We now navigate to the root folder of the web server. To find the location of the root folder, we take a look at the configuration files. The root folder is specified in /etc/nginx/conf.d/default.conf and it’s /usr/share/nginx/html.
Let’s navigate to the root folder and replace index.html with a simple text file. We need to enter the content of the file from the command line, as the container does not have an editor installed (alternatively, we could install one).
mv index.html index_old.html echo This is a file inside the container > index.html
Visit localhost in a browser on the host and the new index.html will appear (press the refresh button if the page doesn’t update, as the old page may be cached).
There is a problem with this approach. The file we created will be lost if the container is removed (e.g., to be replaced by a new version of the server). To save the changes, we’d need to commit them to a new image, which is beyond the scope of this post.
Storage Options in Docker
To share data between the host and the container, we create a folder on the host’s filesystem and mount it to the container’s filesystem. There are two types of storage options in Docker:
- Bind mount: any folder on the host’s filesystem
- Volume: folder managed by the Docker daemon
Bind Mount
Stop and delete the websrv container.
docker stop websrv docker rm websrv
Now, create a directory called html inside the home directory and create a simple index.html file in it.
mkdir html echo This is a file on a bind mount > index.html
We want to mount the html directory to the root directory of the web server inside the container. The -v flag (-v host_directory:container_directory) does that
docker run -p 80:80 -d --name websrv \ –v ~/html:/usr/share/nginx/html \ nginx:latest
The original content of the web server’s root directory is replaced by the content of the mount. Visit localhost from a browser to confirm it worked.
To verify the mount configuration, we can use the inspect command and look for the HostConfig/Binds element in the JSON output.
docker inspect websrv | less
Volume
To show how volumes work, we’re going to repeat the same exercise using a volume instead of a bind mount. As before, stop and remove the existing websrv container, as we’re going to recreate it.
Volumes are managed through the docker volume family of commands. To create a new volume
docker volume create html-volume
To see what directory the volume uses on the host, run the volume inspect command and look for the Mountpoint element in the JSON output
docker volume inspect html-volume
The syntax to use a volume is similar to the case of a bind mount (-v volume:container_directory)
docker run -p 80:80 -d --name websrv \ –v html-volume:/usr/share/nginx/html \ nginx:latest
Differently from bind mounts, the original content of the web server’s root folder is copied into the volume. This happens if the volume is empty, like in this case. If the volume has existing content, that will override the content of the container directory it is mounted to (refer to the documentation).
To remove the volume
docker volume rm html-volume
The command will not remove the volume if it’s used by an existing container. The container will have to be removed first. On the other hand, if the container is removed, the content of the volume is preserved.
1 Pingback