infusion / node-dhcp

A DHCP server and client written in pure JavaScript
https://raw.org/article/a-pure-javascript-dhcp-implementation/
MIT License
301 stars 75 forks source link

Add Dockerfile #46

Closed jgroom33 closed 5 years ago

jgroom33 commented 5 years ago

A Dockerfile should be added that allows this package to run as a container

infusion commented 5 years ago

This is a nice idea, I would propose something like

FROM node:10

USER dhcp

EXPOSE 67/udp

WORKDIR /home/dhcp

RUN mkdir -p /home/dhcp
RUN npm install dhpc

ENTRYPOINT [ "node", "node_modules/dhcp/bin/dhcpd-cli.js" ]

The remaining question is, how could we pass all the options to the dhcpd daemon. Either via env vars, or all within the docker file. What do you think?

Robert

jgroom33 commented 5 years ago

This is an option:

Change CMD to ENTRYPOINT [ "node", "node_modules/dhcp/bin/dhcpd-cli.js" ]

Then the options can be passed during the docker run command.

It's also possible to leave it as CMD and the docker run command could override the entire command (with the options)

Does the current code support environment variables? I presume the most popular use case is to modify the server JavaScript. Possibly, there are use cases that would run multiple docker DHCP containers with different ports exposed. That use case could benefit from environment variables. But the multi container use case could also use a js file for each iteration. That file could be volume mapped during docker run.

infusion commented 5 years ago

The code does not handle env vars at the moment. Everything is passed as argument at the moment. Do you think we should plan for the multiple installation case already or keep it simple for now? BTW: Do you know if EXPOSE exposes UDP ports as well?

jgroom33 commented 5 years ago

The user can figure out how to run multiple. No code changes should be required. Assume they have dhcpserver1.js and dhcpserver2.js ... each would have the options specified for that server. They could run each with: docker run -v dhcpserver1.js:/expected/config/path/config.js -p 1000:68 infusion/node-dhcp:0.0.1

For broadcast DHCP, I think it will be necessary to docker run with --net=host

In cases where there is a router configured for DHCP forwarding, --net=host should not be necessary.

Ports 67/68 are use for DHCP.... 69 is tftp https://en.m.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol

It's possible to expose udp: https://stackoverflow.com/questions/27596409/how-do-i-expose-a-udp-port-on-docker

infusion commented 5 years ago

Port 69 was a typo, sorry. I updated the dockerfile proposal from above. Do you need some additions to that file? You proposal of running multiple instances looks good.

jgroom33 commented 5 years ago

I just tried this and it is close:

FROM node:10

WORKDIR /usr/src/app

COPY . .

RUN npm install

EXPOSE 67/udp

CMD [ "node", "bin/dhcpd-cli.js" ]

No user is necessary because root is used in containers. I changed it to run from the source instead of building from npmjs. This will allow the image to build to trigger on dockerhub without waiting for the lib to publish on npm. read this I also changed it back to CMD. Using CMD allows an override of the default CMD so a user could bash into the container. i.e:

docker run -it infusion/node-dhcp:0.0.1 bash

If ENTRYPOINT is used, this ^ cannot be done.

To execute the container:

docker run -d -p 67:67/udp infusion/node-dhcp:0.0.1 node bin/dhcpd-cli.js --foo-opts

infusion commented 5 years ago

If you want, you can send it together with a little note in the readme as a PR.

Does docker create the workdir itself?

jgroom33 commented 5 years ago

i just tried the above and it does create the directory

jgroom33 commented 5 years ago

it might be possible to have a second dockerfile with the client. Then the two containers could be connected and tested together.

This would be interesting to allow a user to try things while ignoring the dhcp server on their host environment