This post will help you easily get a local web development environment up and running using Docker for Windows. The benefit of this is no need to clutter your host machine with dependencies or install node/npm directly on Windows. Everything will be installed and run inside of Docker containers.

To demonstrate a non-trivial docker setup, we’ll use Docker Compose to create two containers:

  1. A simple GraphQL API container running Apollo Server/Express
  2. An app container served by Vue CLI’s webpack dev server

The github example repo that goes along with this post is at https://github.com/ryancp/tutorial-docker-windows.


There are some prerequisites that are needed before we begin:

  1. Install Docker for Windows Community Edition
    1. I recommend the Stable version
    2. Docker Compose comes included which we’ll use later on
  2. Install Git Bash and Cmder
  3. Clone the tutorial’s repo
    1. git clone https://github.com/ryancp/tutorial-docker-windows.git

The first thing to notice is our deployment/docker-compose.yml file. This is the high level overview of what our application will consist of. You can see that we have our two services defined:

version: '3'

    build: ./base-images/nodejs
    image: tutorial_docker_windows_nodejs
      - ../api:/src
    working_dir: /src
      - PORT=3002
      - NODE_ENV=development
      - 3002:3002
      - 9229:9229
    stdin_open: true
    tty: true
    entrypoint: /bin/bash
    image: tutorial_docker_windows_nodejs
      - ../app:/src
    working_dir: /src
      - PORT=3001
      - HOST=app
      - NODE_ENV=development
      - 3001:3001
    stdin_open: true
    tty: true
    entrypoint: /bin/bash
docker-compose.ymlview rawview file on GitHub

A few other things of note about this docker-compose file are:

  1. We define a base nodejs image that both services will use
  2. Both services will have a volume mounted at /src inside the running container which allows you to store and edit files on your host, but they are also available to the container
  3. Our docker compose project name will be set to “tutorial_docker_windows” later on when we run docker-compose up command

Start Docker Containers

Open a Git Bash terminal and make sure you are in the deployment directory. Then build and run the containers:

$ docker-compose -f docker-compose.yml -p tutorial_docker_windows up --build -d
Start API Service

Now open Cmder and shell into the running api container:

$ docker exec -it tutorial_docker_windows_api_1 bash

We are now inside the api container and can treat this just like a regular Linux environment. From here, we need to install our node_module dependencies.

Our base nodejs image included yarn globally, so I recommend using yarn to install everything (you could also use npm install) as I’ve found it’s faster and less prone to errors than npm:

$ yarn install

After installing, run the GraphQL API server:

$ npm run dev

Test it out by going to http://localhost:3002 and seeing the GraphQL Playground editor. This is an example GraphQL project based on the Apollo Server Getting Started tutorial.

You can paste in the following GraphQL query to the left side and then hit the play button to see the result:

  books {
Start App Service

Open another Cmder tab and shell into the running app container:

$ docker exec -it tutorial_docker_windows_app_1 bash

We are now inside the app container. We need to install our node_module dependencies here also:

$ yarn install

After installing, run the Webpack dev server:

$ npm run dev

Test it out by going to http://localhost:3001 . You should see the example Vue.js app showing the result of the GraphQL “books” query.

To see how volumes work which is what makes the dev environment possible, open app\src\components\HelloWorld.vue file and make any change to the template section, like adding exclamation marks inside the h1 tag on line 3:

<h1>{{ msg }}!!!</h1>

Save the file and switch back to your browser. After a couple seconds, you should see the change without having to reload the browser at all. This is the power of Vue CLI’s Hot Module Reloading feature and because we setup Webpack to watch for changes to our app files (see around line 14 in app\vue.config.js).

Wrap up

That’s really all there is to it.

I hope this has helped you understand how easy it can be to set up a local web development environment for Express and Vue.js based applications.

If you liked this, I plan on doing a follow up post about how to add an Nginx container serving as a reverse proxy to your api and app containers. You will then be able to access them through host names rather than localhost:port.

This is yet another way to enhance your local dev environment and make it closer to production. So stay tuned for that!