Overview

This is a follow up post to my last one . You’ll learn how to add an Nginx container as a reverse proxy serving an api and app container and accessing them through hostnames rather than localhost:port. This provides a benefit of more closely resembling a production environment while you develop locally.

Prereqs/Setup

Please see the previous post for background on how to setup a local web dev environment using Docker for Windows. This will help you understand how we are adding on to include Nginx.

  1. Add hostnames to Windows hosts file
    • Open Notepad as an administrator (start menu, type in “notepad” right click on Notepad icon and select “Run as administrator”.
    • Select Open File and navigate to the etc folder: C:\Windows\System32\drivers\etc.
    • Select “All Files” instead of Text Documents and open the hosts file.
    • Add app and api hostname entries by adding this line to the end of the file
      • 127.0.0.1 app.tutorial.localhost api.tutorial.localhost

Clone this tutorial’s repo:

git clone https://github.com/ryancp/tutorial-nginx-reverse-proxy.git

Take a look at our deployment/docker-compose.yml file. You can see that we have added a gateway service that exposes port 80. This is the only way we will be able to access our upstream services like api and app. We no longer have exposed ports to those containers. Every request will go through our nginx reverse proxy, a.k.a. our gateway service.

version: '3'

services:
  nodejs:
    build: ./base-images/nodejs
  api:
    image: tutorial_nginx_reverse_proxy_nodejs
    volumes:
      - ../api:/src
    working_dir: /src
    environment:
      - PORT=3002
      - NODE_ENV=development
    stdin_open: true
    tty: true
    entrypoint: /bin/bash
  app:
    image: tutorial_nginx_reverse_proxy_nodejs
    volumes:
      - ../app:/src
    working_dir: /src
    environment:
      - PORT=3001
      - HOST=app
      - NODE_ENV=development
    stdin_open: true
    tty: true
    entrypoint: /bin/bash
  gateway:
    build: ../gateway
    volumes:
      - ../gateway:/src
    ports:
      - "80:80"
    depends_on:
      - api
      - app
docker-compose.ymlview rawview file on GitHub

Start Docker Containers

Similar to the previous tutorial. We need to shell into both containers and kick their node process off. 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_nginx_reverse_proxy up --build -d
Start API Service

Now open Cmder and shell into the running api container:

$ docker exec -it tutorial_nginx_reverse_proxy_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://api.tutorial.localhost 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 {
    author
    title
  }
}
Start App Service

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

$ docker exec -it tutorial_nginx_reverse_proxy_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://app.tutorial.localhost . You should see the example Vue.js app showing the result of the GraphQL “books” query.

Create a simple nginx reverse proxy for your local docker web development environment

Nginx Reverse Proxy Tutorial successfully working

Now you no longer need to remember the port numbers of your services and this also more closely resembles a production environment since you can access your services by hostname.

Wrap up

As you can see, this is a very elegant way to access your app and api during development. I hope this gives you a starting point for a setup that you can use for any future web development projects.

In my next post I will show you how to create a self signed certificate that you can add to Windows so that it can be trusted in Chrome while you develop locally and be able to access your services over https.