TCP/Telnet from inside docker container - docker

I have a 'mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim' Docker container, with 2 things on it:
-a custom SDK running on it
-a dotnet5 application that connects to the SDK with TCP
If I connect the the Docker's bash, I can use telnet localhost 54321 to connect to my SDK successfully
If I run the Windows SDK version on my development computer (Windows), and I run my application IIS Express instead of Docker, I can successfully connect with a telnet library (host 'localhost', port '54321'), this works
However, I want to run both the SDK and my dotnet application in a Docker container, and when I try to connect from inside the container (the same thing that works on the IIS hosted version), this does not work. By running 'telnet localhost 54321' from the docker container commandline I can confirm that the SDK is running. What am I doing wrong?
Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
RUN apt-get update && apt-get install -y telnet
RUN apt-get update && apt-get install -y libssl1.1
RUN apt-get update && apt-get install -y libpulse0
RUN apt-get update && apt-get install -y libasound2
RUN apt-get update && apt-get install -y libicu63
RUN apt-get update && apt-get install -y libpcre2-16-0
RUN apt-get update && apt-get install -y libdouble-conversion1
RUN apt-get update && apt-get install -y libglib2.0-0
RUN mkdir /sdk
COPY ["Server/Sdk/SomeSDK*", "sdk/"]
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["Server/MyProject.Server.csproj", "Server/"]
COPY ["Shared/MyProject.Shared.csproj", "Shared/"]
COPY ["Client/MyProject.Client.csproj", "Client/"]
RUN dotnet restore "Server/MyProject.Server.csproj"
COPY . .
WORKDIR "/src/Server"
RUN dotnet build "MyProject.Server.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "MyProject.Server.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyProject.Server.dll"]
Code (working on IIS, when SDK is running on Windows, but not when both SDK and code are running inside the same Docker container):
var telnetClient = new TelnetClient("localhost", 54321, TimeSpan.FromSeconds(1), new CancellationToken());
await telnetClient.Connect();
Thread.Sleep(2000);
await telnetClient.Send("init");
Command line (working BOTH from windows CLI, and from Docker bash (so also when the code is not working, this is working):
$telnet localhost 54321
$init
The issue might be (but I'm not sure, as I've received this result from using direct command line '$telnet localhost 54321' from within dotnet: 'telnet: connection refused by remote host'

Make sure you use in your docker run command also --network=host to use the same network if you want to reach out of the container or create a bridge with --network=bridge (for example with another container).
By default the Docker container is spawn on a separate, dedicated and private subnet on your machine (mostly 172.17.0.0/16) which is different from your machine's default/local subnet (127.0.0.0/8).
For connecting into the host's subnet in this case 127.0.0.0/8 you need --network=host. For communication within the same container though it's not necessary and works out of the box.
For accessing the service in container from the outside you need to make sure you have your application's port published either with --publish HOST_PORT:DOCKER_PORT or --publish-all (random port(s) on host are then assigned, check with docker ps).
Host to container (normal)
# host
telnet <container's IP> 8000 # connects, typing + return shows in netcat stdout
# container
docker run --rm -it --publish 8000:8000 alpine nc -v -l -p 8000
Container to host (normal)
# host
nc -v -l -p 8000
# container, docker run -it alpine
apk add busybox-extras
telnet localhost 8000 # hangs, is dead
Container to host (on host network)
# host
nc -v -l -p 8000
# container, docker run -it --network=host alpine
apk add busybox-extras
telnet localhost 8000 # connects, typing + return shows in netcat stdout
Within container
# start container
docker run -it --name alpine alpine
apk add busybox-extras
# exec into container to create service on 4000
docker exec -it alpine nc -v -l -p 4000
# exec into container to create service on 5000
docker exec -it alpine nc -v -l -p 5000
# telneting from the original terminal (the one with apk add)
telnet localhost 4000 # connects, works
telnet localhost 5000 # connects, works

Related

Not able to access admin console for an activemq instance running in a docker container

I have created dockerfile.
FROM ubuntu:latest
RUN apt-get update && apt-get -y upgrade
RUN apt-get -y install curl
RUN apt-get -y install default-jre
RUN curl -O http://archive.apache.org/dist/activemq/5.16.0/apache-activemq-5.16.0-bin.tar.gz
RUN mkdir -p /opt/apache/activemq
RUN tar xvzf apache-activemq-5.16.0-bin.tar.gz -C /opt/apache/activemq
WORKDIR /opt/apache/activemq/apache-activemq-5.16.0/bin
VOLUME /opt/apache/activemq/apache-activemq-5.16.0/conf
RUN echo './activemq start && tail -f /opt/apache/activemq/apache-activemq-5.16.0/data/activemq.log' > start.sh
# Admin interface
EXPOSE 8161
# Active MQ's default port (Listen port)
EXPOSE 61616
CMD ["/bin/bash", "./start.sh"]
I created a docker container like this
docker run --name activemq -p 8161:8161 -p 61616:61616 temp-activemq:5.16.0
I tried to run the admin console as follows
http:://localhost:8161/admin/
http://<IP of the Container>:8161/admin/
Neither of them works
Outside of the container, I installed activeMQ and tried to run admin console, it worked. Can anyone please help me with pointers on how can I get this sorted?
I fixed the above issue with
docker run --rm -d --network host --name activemq temp-activemq:5.16.0
But, I am still researching why the port forwarding is not working?
I had the same issue. In AMQ 5.16.0 they've updated the jetty.xml for the web UI to use 127.0.0.1 instead of 0.0.0.0!
I fixed it by updating the jetty.xml
update under "org.apache.activemq.web.WebConsolePort" in jetty.xml -->
property name="host" value="127.0.0.1"
to
property name="host" value="0.0.0.0"
You'll need to copy and overwrite this file in your docker image and it should work.

Docker Toolbox refused to connect on the browser - Tried different solutions - Windows 7

I have installed Docker Toolbox on Windows 7.
Everything has been installed correctly.
Now I try to build and run a DockerFile.
Dockerfile
FROM debian:9
RUN apt-get update -yq \
&& apt-get install curl gnupg -yq \
&& curl -sL https://deb.nodesource.com/setup_10.x | bash \
&& apt-get install nodejs -yq \
&& apt-get clean -y
ADD . /app/
WORKDIR /app
RUN npm install
VOLUME /app/logs
CMD npm run start
After successfully running the command line docker build -t test . and docker run -it -d -p 3306:3306 test, I try to access it via my browser by doing :
http://192.168.99.100:3306
which correspond to http://[docker-machine-ip]:port
But it refuses to connect.
After searching on the internet, I tried several solutions:
1. Use the container IP
docker inspect --format '{{ .NetworkSettings.IPAddress }}' [id]
http://[containerIP]:port
2. Add port forwarding on Oracle VM defaut machine
VirtualBox -> Machine settings -> Network -> Adapter 1 (NAT) -> Advanced, Port Forwarding
name : test
Host ip : 127.0.0.1
Host port : 3306
Guest port : 3306
I even tried by putting Guest IP to 192.168.99.100 and letting Host IP to empty.
3. Try different ports
I tried differents ports to see if it was not caused by a port already opened.
I even tried the option --publish-all (-P) but as a result, I don't have any ports showing on docker ps -a
docker run -it -d -P test
4. Deactivate the windows firewall
Both public and private.
None of those solutions worked for me and I don't know what to do next.
Any help ? I would appreciate. Thank you.

How to access host localhost (for instance 127.0.0.1:22334) from inside a docker container inside a Windows Subsystem for Linux

Suppose I have a server running on port 8000 on Windows. How can my Docker container access it via 127.0.0.1:8000? I can't change the hostname too as the app in the container is not in my control.
I've read this previous discussion same but inside VB on using "--network=host" for a container to access the host machine's network, or using some different ip for the localhost. However, I'm on Windows and Docker runs inside a Windows Subsystem for Linux (ubuntu from the windows store) so localhost from the Docker container with --network="host" does not get it right. From inside the Windows Subsystem for Linux I can access 127.0.0.1:8000 without problems.
For instance, having some bash file doing the following
#!/bin/bash
set -x
# we get some file from the localhost
curl 127.0.0.1:22334/some_file.txt
# we build docker image
docker build --tag dockername --network=host dockerfiles/imagename
and some docker file like this
# This is a Dockerfile
FROM ubuntu:16.04 as installer
RUN apt-get update && apt-get install --no-install-recommends curl -y
RUN curl 127.0.0.1:22334/some_file.txt
I get something like
+ curl 127.0.0.1:22334/some_file.txt
here_we_get_some_file_content
+ docker build --tag dockername --network=host dockerfiles/imagename
Sending build context to Docker daemon 18.43kB
Step 1/30 : FROM ubuntu:16.04 as installer
---> 4a689991aa24
Step 2/30 : RUN apt-get update && apt-get install --no-install-recommends curl -y
---> Running in 72378a1be045
...
Step 3/30 : RUN curl 127.0.0.1:22334/some_file.txt
---> Running in 41a4c470337b
curl: (3) <url> malformed
The command '/bin/sh -c curl 127.0.0.1:22334/some_file.txt' returned a non-zero code: 3

Website locally hosted by a Docker for Windows windows container is unavailable via localhost

I am attempting to set up a Docker for Windows container to build and host a simple static website using lite-server and Sphinx. I first run the container.
$ docker run -it -p 8080:8080 -v "$(pwd):C:\src" website
And then start lite-server.
$ yarn serve
The website is available from the container's IP address (e.g., http://172.26.141.28:8080) so I know lite-server is serving the content, but I cannot access the content with http://localhost:8080.
How can I expose the website via localhost:8080?
My Dockerfile is as follows
FROM microsoft/windowsservercore
ENV chocolateyUseWindowsCompression false
RUN powershell -Command \
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'));
RUN choco install nodejs -y
RUN choco install yarn -y
RUN choco install python3 -y
RUN pip install sphinx
RUN pip install sphinx_rtd_theme
# https://github.com/nodejs/node/issues/8897#issuecomment-319010735
# Workaround for error An unexpected error occurred: "ENOENT: no such file or directory, lstat 'C:\\ContainerMappedDirectories'".
RUN mkdir C:\src
RUN powershell Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices' -Name 'S:' -Value '\??\C:\src' -Type String
WORKDIR 'S:\\'
EXPOSE 8080
CMD ["powershell"]
lite-server is launched with
"scripts": {
"serve": "light-server -s ./build/html -p 8080"
},
Software:
Docker version 17.06.2-ce, build cec0b72
Windows 10 (host)
Windowsservercore (container)
I don't know if there's been an update, but as of a year ago, this was the expected behavior:
containers and their ports are only accessible via the NATed IP address.
see: https://github.com/docker/for-win/issues/204#issuecomment-258638899.
Your docker file says you are exposing the port at 8080 and you are mapping at 8091.
try to run the following command,
docker run -it -p 8080:8080 -v "$(pwd):C:\src" website
You should able to navigate it to http://localhost:8080
Hope it helps.

Rails app docker container not accessible from Windows host

I am trying to make a simple docker container that runs the Rails app from the directory that I launch it in.
Everything appears to be fine except when I run the container and try to access it from my Windows host at the IP address that Docker Machine gives me, it responds with a connection refused error message.
I even used the Nginx Dockerfile as a reference, because the Nginx Dockerfile actually builds a container that is accessible for me.
Here is my Dockerfile so far:
FROM ruby:2.3.1
RUN gem install rails && \
apt-get update -y && \
apt-get install -y nodejs
VOLUME ["/web_app"]
ADD . /web_app
WORKDIR /web_app
RUN bundle install
CMD rails s -p 80
EXPOSE 80
I build the image using this command
docker build -t rails_server .
I then run it using this command
docker run -d -p 80:80 rails_server
And here is what I try to access the webpage:
curl $(docker-machine ip)
And this is what I get back:
curl: (7) Failed to connect to 192.168.99.100 port 80: Connection refused
And this is how it makes me feel:
The problem here seems to be that the app is listening on 127.0.0.1:80, so the service will not accept connection from outside the container. Could you check if modifying the rails server to listening on 0.0.0.0 the issue solves?
You can do that using the -b flag of rails s:
FROM ruby:2.3.1
RUN gem install rails && \
apt-get update -y && \
apt-get install -y nodejs
VOLUME ["/web_app"]
ADD . /web_app
WORKDIR /web_app
RUN bundle install
CMD rails s -b 0.0.0.0 -p 80
EXPOSE 80
The port is only exposed to the vm running the docker inside. You have to still expose port 80 of your vm to your local machine so it can connect to it. I think the best approach is making your container to be listened o an optional port like 7070 and then using a simple nginx proxy pass to feed the content to the outside (listening on port 80)

Resources