I have tried everything I can think of. I have read the docs, blogs and tried following samples on github.
But I can't seem to get it to work.
What I want to do is simple. I want to write my node.js code on my windows 8.1 machine, and I also want to run the code from within a Docker container without having to rebuild the container all the time. So I want to map a directory on my Windows Host to a directory inside the container.
I have created this Dockerfile
FROM node:0.10.38
RUN apt-get update -qq && apt-get install -y build-essential
ENV ZMQ_VERSION 4.1.3
ENV LIBSODIUM_VERSION 1.0.3
RUN curl -SLO "https://download.libsodium.org/libsodium/releases/libsodium-$LIBSODIUM_VERSION.tar.gz" \
&& tar xvf libsodium-$LIBSODIUM_VERSION.tar.gz \
&& cd libsodium-$LIBSODIUM_VERSION \
&& ./configure \
&& make \
&& make install \
&& cd .. \
&& rm -r libsodium-$LIBSODIUM_VERSION \
&& rm libsodium-$LIBSODIUM_VERSION.tar.gz
RUN curl -SLO "http://download.zeromq.org/zeromq-$ZMQ_VERSION.tar.gz" \
&& tar xvf zeromq-$ZMQ_VERSION.tar.gz \
&& cd zeromq-$ZMQ_VERSION \
&& ./configure \
&& make \
&& make install \
&& cd .. \
&& rm -r zeromq-$ZMQ_VERSION \
&& rm zeromq-$ZMQ_VERSION.tar.gz
RUN ldconfig
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
RUN mkdir -p /usr/src/app
ADD . /usr/src/app
WORKDIR /usr/src/app
RUN npm install
EXPOSE 3000
EXPOSE 35729
CMD ["npm", "start"]
I have this simple server.js file
var express = require('express');
var app = express();
var zmq = require('zmq');
app.get('/', function (req, res) {
res.send('ZMQ: ' + zmq.version);
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
And this simple package.json
{
"name": "docker-node-hello-world",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.13.3",
"zmq": "^2.14.0"
}
}
I have installed the latest Docker Toolbox, and can run the Docker Hello World example fine. I try to build my docker image like this when I am in the directory where my Dockerfile is.
docker build -t dockernodetest:dockerfile .
I then try to run it, also from the same location inside the Docker Quickstart Terminal. I use the hash since the tag doesn't take for some reason:
docker run -v //c/Bitbucket/docker-node-hello-world/:/usr/src/app -p 3000:3000 -i -t 9cfd34e046a5 ls ./usr/src/app
The result of this is an empty directory. I was hoping I could just invoke
docker run -v //c/Bitbucket/docker-node-hello-world/:/usr/src/app -p 3000:3000 -i -t 9cfd34e046a5 npm start
But since the host directory isn't available it fails. I have the feeling that I have misunderstood something very basic. I just don't know what.
First let's start from the Dockerfile
FROM node:0.10.38-onbuild
RUN apt-get update -qq && apt-get install -y build-essential
ENV ZMQ_VERSION 4.1.3
ENV LIBSODIUM_VERSION 1.0.3
RUN curl -SLO "https://download.libsodium.org/libsodium/releases/libsodium-$LIBSODIUM_VERSION.tar.gz" \
&& tar xvf libsodium-$LIBSODIUM_VERSION.tar.gz \
&& cd libsodium-$LIBSODIUM_VERSION \
&& ./configure \
&& make \
&& make install \
&& cd .. \
&& rm -r libsodium-$LIBSODIUM_VERSION \
&& rm libsodium-$LIBSODIUM_VERSION.tar.gz
RUN curl -SLO "http://download.zeromq.org/zeromq-$ZMQ_VERSION.tar.gz" \
&& tar xvf zeromq-$ZMQ_VERSION.tar.gz \
&& cd zeromq-$ZMQ_VERSION \
&& ./configure \
&& make \
&& make install \
&& cd .. \
&& rm -r zeromq-$ZMQ_VERSION \
&& rm zeromq-$ZMQ_VERSION.tar.gz
RUN ldconfig
EXPOSE 3000 35729
From line 1 I've used the 0.10.38-onbuild tag because I want to take advantage of onbuild scripts that will run to create the /usr/src/app directory and run npm install
Then server.js and package.json are as you have written them. These are both in the same working directory as the Dockerfile as well.
Next we build the image
docker build -t dockernodetest .
I've omitted the dockerfile tag as it seemed unnecessary. The client will automatically add a latest tag anyway. To see what images you've have locally run docker images.
At this point we should have an image ready to run but let us first check that the files we wanted to load are then and that npm install created the node_modules directory
$ docker run dockernodetest ls /usr/src/app
Dockerfile
node_modules
package.json
server.js
We're ready at this point to run our little nodejs app
$ docker run -it -p 8080:3000 dockernodetest
> [email protected] start /usr/src/app
> node server.js
Example app listening at http://0.0.0.0:3000
In this instance I've used the -p 8080:3000 flag to map the container's 3000 port to port 8080 on my host machine. Note that I didn't have any other commands at the end because the -onbuild image I've pulled form has a CMD [ "npm", "start" ] and so the default action is to run the start package script.
So to make the development cycle even faster you want to mount your working directory to the container via the -v option
$ docker run -it -p 8080:3000 -v "$PWD":/usr/src/app dockernodetest
> [email protected] start /usr/src/app
> node server.js
module.js:340
throw err;
^
Error: Cannot find module 'express'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/usr/src/app/server.js:1:77)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
npm ERR! Linux 4.1.7-15.23.amzn1.x86_64
npm ERR! argv "node" "/usr/local/bin/npm" "start"
npm ERR! node v0.10.38
npm ERR! npm v2.11.1
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `node server.js`
npm ERR! Exit status 8
But what's happened here? Because we mounted the current working directory it overwrote what was previously there in /usr/src/app including our node_modules directory.
So the quick fix here is to now run a npm install in our current working directory and rerun the docker run command.
$ npm install
[email protected] /home/ec2-user/dockernode
└─┬ [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
...
$ docker run -it -p 8080:3000 -v "$PWD":/usr/src/app dockernodetest
> [email protected] start /usr/src/app
> node server.js
Example app listening at http://0.0.0.0:3000
Now if you make an update to your server.js file just hit Ctrl+c and restart you docker image though you might want to use something like nodemon to make this even more seamless.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With