I recently wanted to test a web app written in Node.js and exposed via fixed port. The instructions asked me to install Node.js locally, which I resist! So, here is how I built my Docker container to run the code.

My goal is to use the official Node.js image and “inject” the code and startup command I need, while saving selected output files on my host machine. Plus I need my browser to access the web app without conflicting ports (since I already have Apache running locally).

Of course, if the software was provided as a container, then all this would be redundant. Also, this post is simply another alternative - I could just use the standard Node.js image to run code on my host machine as I did previously, unless you are worried about “untrusted” code like I am!

The previous posts are Setting up Node.js in a Docker container, where I use the standard container (for the most part) to run code locally, followed by Wiring up Node.js and MongoDB containers, where I wireup (network) standard containers.

Assume:

  • The code comprises of folders like this:
    my_software
    ├─ bin
    └─ saves
  • I want to map the saves folder to my local folder
  • The start up script for the code is basically:
    cd my_software
    node start_server.js

Here is what I did:

  1. To build the container from the standard Node.js image:

    docker create --name my_container -v "$PWD/saves":/my_software/saves -p 3300:8000 -w /my_software/bin --entrypoint node node start_server.js
    • --name to name the container
    • -v bind to volume to a local folder
    • -p publish container port 8000 to the host as 3300 to avoid conflicts
    • -w the working directory to start the executable in (I reference the current directory with $PWD) - it’s important to set this to whatever the original startup script specified
    • --entrypoint - specifies the executable node to be run when the container starts, and also provide start up argument start_server.js
    • Note that the second node in the command is the image to pull from Docker Hub, maybe it’s better to be explicit with node:latest

      I also tried docker run -d --name my_container -v "$PWD/saves":/my_software/saves -p 3300:8000 -w /my_software/bin --entrypoint node node start_server.js - this works for me too.

  2. At this stage, the container won’t start properly, because the source code doesn’t exist in the standard node.js image! So, to copy the source code into the root folder of the container (you need to be in the parent folder where my_software is a sub-folder):

    docker cp my_software my_container:/
  3. Finally to start the container (which, remember, runs as a daemon, in the background):

    docker start my_container

This will start the container using the parameters we defined previously, including starting the correct code file in the correct folder, exposing the port and allowing files to be saved locally. No Dockerfile and no interactive-followed-by-commit.

Just to finish up:

  • To stop the container docker stop my_container
  • To list running containers docker ps
  • To remove the container for good docker rm my_container
  • To remove the Node.js image docker rmi node