Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

running netcat inside docker container

I have created docker images using the below Dockerfile.

 FROM ubuntu
 RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    net-tools \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*
RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    netcat \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*
EXPOSE 1234
ENTRYPOINT bin/bash
CMD ["nc", "-l", "1234"]

I created image from the above docker file and run the docker container using the image by running below command.

docker run -d  -i -p 1234:1234 --name daemon  nc-ubuntu nc -l 1234

In another terminal, I run the below command.

telnet localhost 1234

I got the below output.

$ telnet localhost 1234
Trying ::1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

I am trying this as this is sample from book docker in practice in chapter 2 by manning for running docker as daemon process.

As per author I should get below result.

$ telnet localhost 1234
Trying ::1...
Connected to localhost.
Escape character is '^]'.
hello daemon

Any idea why I'm not getting expected output.

like image 647
Rajkumar Natarajan Avatar asked Sep 10 '17 16:09

Rajkumar Natarajan


Video Answer


2 Answers

That's never going to work. There are several problems with your Dockerfile.

1

Setting ENTRYPOINT to /bin/bash means that docker run ... is simply going to start bash. Read this question about ENTRYPOINT and CMD.

2

Since you're in non-interactive mode, bash is going to exit immediately. Consider:

host$ docker run nc-ubuntu
host$

Vs:

host$ docker run -it nc-ubuntu
root@e3e1a1f4e453:/# 

The latter, because of the -it (which allocates a tty device, which bash requires in interactive mode), gets a bash prompt.

3

Neither invocation will cause the container to run netcat...and even if it did, nothing in your Dockerfile would generate the hello daemon response you're expecting.

4

The nc command line is incorrect. The syntax is:

nc -l -p <port>

So you would need:

CMD ["nc", "-l", "-p", "1234"]

5

If you actually want nc to provide you with the hello daemon response, you would need to add an appropriate -c command to your nc command line, as in:

CMD ["nc", "-l", "-p", "1234", "-c", "echo hello daemon"]

This makes the final Dockerfile look like:

FROM ubuntu
RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    net-tools \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*
RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    netcat \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*
EXPOSE 1234
CMD ["nc", "-l", "-p", "1234", "-c", "echo hello daemon"]

And if I build that:

docker build -t nc-ubuntu .

And run that:

docker run -d  -i -p 1234:1234 --name daemon  nc-ubuntu

I can then telnet to port 1234 on my host and see the expected response:

host$ telnet localhost 1234
Trying ::1...
Connected to localhost.
Escape character is '^]'.
hello daemon
Connection closed by foreign host.

At this point, the container will have exited because nc exits after accepting a single connection (without additional parameters), and a Docker contain exits when the foreground process exits.


I don't have access to the book so I can't tell if this is do to a problem with the book or if you have made a mistake in your implementation, but I would suggest that there are a number of online Docker tutorials that are probably at least as good.

like image 165
larsks Avatar answered Oct 11 '22 07:10

larsks


A simple solution that works for me - docker run -p 1234:1234 -it --rm alpine /bin/sh -c "nc -l -p 1234"

From another terminal run nc localhost 1234

like image 3
Avik Chakraborty Avatar answered Oct 11 '22 07:10

Avik Chakraborty