Skip to content
This repository has been archived by the owner on Feb 5, 2021. It is now read-only.
/ cowsay-express Public archive

Learn how to Dockerise a Node application. Run it in the cloud and then run it locally in prod and dev modes. And, most importantly, have fun! ☕

Notifications You must be signed in to change notification settings

cassilup/cowsay-express

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Docker for WebDevs Workshop

Welcome, this is a tutorial on Docker-ising a WebApp.

If you're curious about the tutorial's context, check out the presentation slides. slides

The tutorial consists of 5 main parts:

  1. Running the example app locally
  2. Create the Dockerfile
  3. Deploying the app to the cloud and have it built using the Dockerfile
  4. Running the example app locally in a Docker container (Production Mode)
  5. Running the example app in a Docker container listening for code changes (Development Mode)

1. Running the example app locally

1.1. Clone the repo

git clone https://github.com/cassilup/express-cowsay

1.2. Since this is a node.js app, we need to grab the needed packages from npm

npm install

If all went well, you now have a new folder named node_modules/.

1.3. Start the app by running:

node index.js

You should see the following in your terminal: app running natively

1.4. Open http://localhost:8080 in your browser.

You should see the following: app running natively

1.5. Stop the app and clean the project

We want to reset the project to its original state, without any npm packages installed. That is because we will start the server inside a Docker container and the node_modules/ folder will be created inside the container, without our

First, we will stop the server by hitting CTRL+C.

Secondly, we will delete the node_modules/. We will later generate it from inside of our Docker container.


2. Create the Dockerfile

This is the magical part. Dockerfile is like a recipe. It builds our project environment based on the ingredients (instructions) we specify here.

Here is the Dockerfile that we'll be using for this tutorial:

FROM node:boron

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY package.json /usr/src/app

RUN npm install

COPY . /usr/src/app

EXPOSE 8080

CMD [ "npm", "start" ]

Each step in the Dockerfile generates an intermediate container. This is the strategy that allows Docker to be fast.

Few Dockerfile keywords that you should be aware of:

  • FROM: Image that our container will be built from. (Note: you can build/package/deploy your own images.)
  • RUN: Execute a command in the bash of our Linux container.
  • WORKDIR: Equivalent of cd <path/to/folder>
  • COPY: Copies files from the host machine (your native OS) to the container's filesystem.
  • EXPOSE: Opens up a port so that we can access our container.
  • CMD: Special command that is run every time the container is started.

For more info about possible keywords, click here.


3. Deploying the app to the cloud and have it built using the Dockerfile

3.1. Install now.sh

Follow the official instructions.

3.2. Run the following command

now --docker

Notice the new URL for our deployed app in the command line: docker building image

3.3. Access the app's URL

Accessing that URL returns information about our deployment: docker building image

Notice that the local terminal mirrors the same logs we can see in the browser: docker container being deployed docker container finished deploying

Once the deployment is ready, we can see our app running from a Docker container in the app's URL: app running in the cloud

Awesome!


4. Running the example app locally in a Docker container (Production Mode)

Note: Make sure you have Docker for Mac/Win installed.

For more information on the VM used by Docker, click here.

Steps to generate a Docker image out of our Dockerfile:

4.1. Build the project into a Docker image

docker build -t cowsay-express .

Notice the intermediate containers being created. docker building image

4.2. Start a container from the image we just built

docker run -p 10080:8080 -d cowsay-express

docker successfully built image

4.3. Navigate to http://localhost:10080 and voilá!

node app running in Docker

Very Important: Notice that there's no node_modules/ in our code. This means that the app is actually running in the Docker container.

4.4. Access the internal folder structure of the container by opening a shell inside it

docker exec -it <container id> sh

Now list the contents of the app's folder and notice the node_modules/ folder being present:

ls -l /usr/src/app

node_modules present

Other useful commands:

  • docker images —> lists all images on system
  • docker ps —> lists running containers on system
  • docker ps -a —> lists all containers
  • docker stop <container id> -> stop a container
  • docker rm <container id> -> remove a container
  • docker image rm <image name> -> remove an image

For more info, click here


5. Running the example app in a Docker container listening for code changes (Development Mode)

By default, node doesn't "listen" for code changes. So when you make code changes, you need to restart the node process in order to have it take changes into account.

nodemon is a tool that fixes that and is commonly used in development of node projects.

In order to be able to develop in our own host OS and have the code changes reflected inside and served through the Docker container, we have to:

  1. Install nodemon into the container at build time (by adding it to our Dockerfile).
  2. Mount the source of the app as a shared folder from our host OS to the Docker container (by using docker-compose).

The steps we need to take are:

5.1. Create a new file docker-compose.yml:

version: "2"

services:
  web:
    build: .
    command: nodemon --inspect=5858
    volumes:
      - .:/usr/src/app
      - /usr/src/app/node_modules
    ports:
      - "10080:8080"
      - "5858:5858"

Through this file, we're telling Docker to mount our current folder as a shared folder in the container's filesystem.

Mounting our current folder enables us to make changes and have them be served directly from the container as they occur.

Note: We need the - /usr/src/app/node_modules line in order to have the node_modules/ folder persisted as intermediate containers are being built.

5.2. Install nodemon through Dockerfile

Add the following line to the Dockerfile:

FROM node:boron

RUN npm i -g nodemon           # <-- New Line

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY package.json /usr/src/app

RUN npm install

COPY . /usr/src/app

EXPOSE 8080

CMD [ "npm", "start" ]

5.3. Run docker-compose up in order to bring up the project with the mounted folder and nodemon listening for changes:

docker-compose running

5.4. Navigate to http://localhost:10080

node app running in Docker

5.5. Make a change in the code and reload http://localhost:10080

container showing changes

Bonus: You can debug the Node app directly in the browser.

Congrats. You're now a Docker guru (almost). 😎


Thanks for reading so far down! If you find any inconsistencies, please be sure to let me know. I hope this tutorial got you on the right track, Docker-wise.

If you enjoyed this, drop me a line! I'd love to hear from you.

About

Learn how to Dockerise a Node application. Run it in the cloud and then run it locally in prod and dev modes. And, most importantly, have fun! ☕

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published