Tutorial: How to Use Docker Volumes to Code Faster

Published on May 20, 2020

If you are a developer who uses Docker, odds are you may have heard that you can use volumes to maintain persistent state for your containers in production. But what many developers don’t realize is that volumes can also be an excellent tool for speeding up your development workflow.

In this post, I’ll give you a brief overview of what is a Docker volume, how docker host volumes work, and show you a tutorial and example of how you can use volumes and nodemon to make coding with Docker easier and faster.

What Is a Volume?

Volumes are a special type of folder that is accessible by a docker container. Unlike regular folders, volumes have a life-cycle independent of the containers in which they’re mounted. That’s because they are stored outside of a container. As a result, volumes make it easy to persist data even when containers die to and share data between containers and the host.

Docker allows you to use a variety of methods to implement volumes. Some of them are focused on making it easy to share data between containers on the same host. Others allow you to store data on an external file system, such as an NFS volume mount. In this article, we’re going to focus on a type of volume known as host volumes, which can be used to make it easier and faster to work with a container’s code.

Host Volumes

Host volumes allow you to mount a folder on your laptop into a container. And that turns out to be super helpful in speeding up your development process.

Host volumes sync file changes between a local host folder and a container folder. So if you use a host volume to mount code you’re working on into a container, any edits you make to your code on your laptop will automatically appear in the container.

Without this approach, every time you want to test your code, you have to rebuild the container it’s stored in. But if you mount your code as a host volume, you can configure that container to sync code changes as you make them.

To illustrate this, we’ll use a Node.js example: Node-todo, a simple to-do application created by scotch.io. To clone the repo:

$ git clone https://github.com/kelda-inc/node-todo

The repo is designed to work with Docker Compose. It also works with Blimp, an alternative to Compose that runs in the cloud.

Here’s Node-todo’s docker-compose.yml:

version: '3'
services:
  web:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - mongo
    volumes:
      - "./app:/usr/src/app/app"
  mongo:
    image: "mongo"
    ports:
      - "27017:27017"

This file tells Docker to boot a container, the application, and a MongoDB database that the application uses to store the to do’s. It also tells Docker to mount a host volume:

volumes:
  - "./app:/usr/src/app/app"

As a result, Docker will mount the ./app directory on your laptop, which contains your code, into the container at /usr/src/app/app.

Now what we need to do is ensure that the node process will restart whenever you’ve edited your code. For that, we’ll use nodemon.

nodemon is a Node.js package that automatically restarts an application when it detects file changes in one or more specified directories. When you change your code on your laptop/desktop, nodemon detects that the code has changed and restarts the process.

So, in the Dockerfile we set the entrypoint to nodemon instead of node.js:

FROM node:10-alpine
ENV PORT 8080
WORKDIR /usr/src/app
COPY . /usr/src/app

RUN npm install -g nodemon
RUN npm install

ENTRYPOINT ["nodemon", "/usr/src/app/server.js"]

In this example, we’ve shown you how you can use a host volume and nodemon to automatically sync your code between your laptop and your container. If you hadn’t mounted your code in the host volume, you’d have to rebuild the container each time you wanted to test a change. Depending on your application, that can chew up a lot of time.

And by saving you time, this technique also makes it easier for you to write great code. If you need to stop and wait every time you need to test a change, it’s challenging to maintain a state of flow. Add in all the other distractions you have to deal with, and it’s not a recipe for being productive.

Syncing Your Code When Developing Your Application

In this section, we’ll describe how to take one of your existing projects and enable synching for rapid development just like we did above.

In this example, we’ll use Node.js. In future posts, we’ll provide examples for other languages.

Prerequisites

Just like the example above, your project needs to have:

How to Configure Your Container to Sync Your Code Automatically

1) Find the folder in your Docker container that has your code. The easiest way to figure out where your code is located in your container is to look at the COPY commands in your Dockerfile. In the Node-todo example, you can see from its Dockerfile that the code is located in . /usr/src/app:

COPY . /usr/src/app

2) Find the path to the folder on your laptop that has the same code.

3) Add a host volume to your docker-compose file. Find the container in your docker-compose file that you want to sync code with, and add a `volume’ instruction underneath that container:

volumes:
  "/path-to-laptop-folder:/path-to-container-folder"

4) Switch from using node.js to nodemon. In the Node-todo example, we implemented it using its Dockerfile:

RUN npm install -g nodemon
RUN npm install

ENTRYPOINT ["nodemon", "/usr/src/app/server.js"]

As a result, Docker will install nodemon with npm install -g nodemon and change the entrypoint from node to nodemon.

5) Run Docker Compose or Blimp. Now all you need to do is either run docker-compose:

$ docker-compose up

Or if you’re using Blimp:

$ blimp up

Docker will overwrite the code that was built into the container with the code you’ve got running locally on your laptop.

And you’re all set! By modifying your project so it uses a host volume and nodemon, any changes you make to the code on your laptop will now automatically appear in the container.

Conclusion

Docker volumes were originally designed to make it easier to work with local files. But as we’ve seen in this article, they’re also a great way to make development easier and faster. It may take you a little time to get comfortable using volumes as part of your development process. But in the long run, you’ll be glad you switched to using them.

Resources

Read about common mistakes with host volumes that can slow down your application.

Learn about Blimp’s design principles for how we’re improving developer productivity for container development.

Join our Slack community!

Related Article

How We Cut Our Docker Push Time by 90%

Read Now →