Windows Docker Trying to run a service - docker

I'm not sure where this is going wrong at all but I'm new to containers and trying to learn as I go.
I'm trying to containerize a windows service/application and expose a port via a container but can't quite tell how I investigate where it's failing.
I should point out that I'm running this on Server 2019 Datacentre inside VMWare Player.
Dockerfile:
# escape=`
FROM mcr.microsoft.com/windows/servercore:10.0.17763.2300-amd64
RUN powershell -Command `
Add-WindowsFeature Web-Server; `
Invoke-WebRequest -UseBasicParsing -Uri "https://dotnetbinaries.blob.core.windows.net/servicemonitor/2.0.1.10/ServiceMonitor.exe" -OutFile "C:\ServiceMonitor.exe"
EXPOSE 80
ENTRYPOINT ["C:\\ServiceMonitor.exe", "w3svc"]
COPY installer.exe ./
COPY service_start.ps1 ./
RUN powershell -Command `
Start-Process C:\\installer.exe -ArgumentList '-i -nomsg'` -Wait
CMD ["powershell.exe", "C:\\service_start.ps1"]
EXPOSE 1950
Now in theory, this docker file should create an IIS setup along with installing my service. IIS will run on port 80, my service will communicate on port 1950.
The service_start.ps1 contains:
Start-Service -Name "STO Controller"
which is the name of the service I'm installing (and works locally)
In PS, I run:
docker build -t STOBASE .
and the build process is successful.
I then run:
docker run -p 1000:80 -p 1001:1950 -dit STOBASE
This creates the container and I can see that the IIS portion forces it to stay active
docker ps a
shows that this is definitely running.
I open a browser and go to http://localhost:1000 and see the IIS splash screen so this part works
http://localhost:1001 should display the splash screen for the service.
MY first thought is that servercore is missing a dependancy as I don't know a lot about the service I'm installing other than it seems to have an integrated webserver due to the fact it serves up a webpage that is accessible on port 1950 from another machine.
Any ideas what I've missed or how I investigate this?

Related

Docker Port mapping resulting in ERR_EMPTY_RESPONSE [duplicate]

I've been trying to figure this out in the last hours but I'm stuck.
I have a very simple Dockerfile which looks like this:
FROM alpine:3.6
COPY gempbotgo /
COPY configs /configs
CMD ["/gempbotgo"]
EXPOSE 8025
gempbotgo is just an go binary which runs a webserver and some other stuff.
The webserver is running on 8025 and should answer with an hello world.
My issue is with exposing ports. I ran my container like this (after building it)
docker run --rm -it -p 8025:8025 asd
Everything seems fine but when I try to open 127.0.0.1:8025 in the browser or try a wget i just get an empty response.
Chrome: ERR_EMPTY_RESPONSE
The port is used and not restricted by the firewall on my Windows 10 system.
Running the go binary without container just on my "Bash on Ubuntu on Windows" terminal and then browsing to 127.0.0.1:8025 works without a hitch.
Other addresses returned a "ERR_CONNECTION_REFUSED" like 127.0.0.1:8030 so there definetly is something active on the port.
I then went into the conatiner with
docker exec -it e1cc6daae4cf /bin/sh
and checked in there with a wget what happens. Also there no issues. index.html file gets downloaded with a "Hello World"
Any ideas why docker is not sending any data? I've also ran my container with docker-compose but no difference there.
I also ran the container on my VPS hosted externally. Same issue there... (Debian)
My code: (note the Makefile)
https://github.com/gempir/gempbotgo/tree/docker
Edit:
After getting some comments I changed my Dockerfile to a multi-stage build. This is my Dockerfile now:
FROM golang:latest
WORKDIR /go/src/github.com/gempir/gempbotgo
RUN go get github.com/gempir/go-twitch-irc \
&& go get github.com/stretchr/testify/assert \
&& go get github.com/labstack/echo \
&& go get github.com/op/go-logging
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY configs ./configs
COPY --from=0 /go/src/github.com/gempir/gempbotgo/app .
CMD ["./app"]
EXPOSE 8025
Sadly this did not change anything, I kept everything as close as possbile to the guide here: https://docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds
I have also tried the minimalist Dockerfile from golang.org which looks like this:
FROM golang:onbuild
EXPOSE 8025
But no success either with that.
Your issue is that you are binding to the 127.0.0.1:8025 inside your code. This makes the code work from inside the container but not outside.
You need to bind to 0.0.0.0:8025 to bind to all interfaces inside the container. So traffic coming from outside of the container is also accepted by your Go app
Adding to the accepted answer: I had the same error message trying to run docker/getting-started.
The problem was that "getting-started" is using port 80 and this was
"occupied" (netsh http show urlacl) on my machine.
I had to use docker run -d -p 8888:80 docker/getting-started where
8888 was an unused port. And then open "http://localhost:8888/tutorial/".
I have the same problem using Dockerize GatsbyJS. As Tarun Lalwani's comment above, I resolved the problem by binding or using 0.0.0.0 as hostname
yarn develop -P 0.0.0.0 -p 8000
For me this was a problem with the docker swarm mode ingress network. I had to recreate it. https://docs.docker.com/network/overlay/#customize-the-default-ingress-network
Another possibility why you are getting that error is that the docker run command is run through a normal cmd prompt and not the admin command prompt. Make sure you run as an admin!

Unable to reach my application from outside Docker container but everything works inside the container

I'm trying to run Rhino Compute in a docker container and facing a weird issue. I had built an image using the Dockerfile below and when I run it locally, there are no issues.
# escape=`
# see https://discourse.mcneel.com/t/docker-support/89322 for troubleshooting
# NOTE: use 'process' isolation to build image (otherwise rhino fails to install)
### builder image
FROM mcr.microsoft.com/dotnet/sdk:5.0 as builder
# copy everything, restore nuget packages and build app
COPY src/ ./src/
RUN dotnet publish -c Release -r win10-x64 --self-contained true src/compute.sln
### main image
# tag must match windows host for build (and run, if running with process isolation)
# e.g. 1903 for Windows 10 version 1903 host
FROM mcr.microsoft.com/windows:1809
#Copy the fonts and font install script
COPY fonts/* fonts/
COPY InstallFont.ps1 .
#Run font install scriptin powershell
RUN powershell -ExecutionPolicy Bypass -Command .\InstallFont.ps1
# install .net 4.8 if you're using the 1809 base image (see https://git.io/JUYio)
# comment this out for 1903 and newer
RUN curl -fSLo dotnet-framework-installer.exe https://download.visualstudio.microsoft.com/download/pr/7afca223-55d2-470a-8edc-6a1739ae3252/abd170b4b0ec15ad0222a809b761a036/ndp48-x86-x64-allos-enu.exe `
&& .\dotnet-framework-installer.exe /q `
&& del .\dotnet-framework-installer.exe `
&& powershell Remove-Item -Force -Recurse ${Env:TEMP}\*
# install rhino (with “-package -quiet” args)
# NOTE: edit this if you use a different version of rhino!
# the url below will always redirect to the latest rhino 7 (email required)
# https://www.rhino3d.com/download/rhino-for-windows/7/latest/direct?email=EMAIL
RUN curl -fSLo rhino_installer.exe https://www.rhino3d.com/download/rhino-for-windows/7/latest/direct?email=<myemail> `
&& .\rhino_installer.exe -package -quiet `
&& del .\rhino_installer.exe
# (optional) use the package manager to install plug-ins
# RUN ""C:\Program Files\Rhino 7\System\Yak.exe"" install jswan
# copy compute app to image
COPY --from=builder ["/src/dist", "/app"]
WORKDIR /app
# bind rhino.compute to port 5000
EXPOSE 5000
# uncomment to build core-hour billing credentials into image (not recommended)
# see https://developer.rhino3d.com/guides/compute/core-hour-billing/
#ENV RHINO_TOKEN=
CMD ["rhino.compute/rhino.compute.exe"]
Application code is here: https://github.com/mcneel/compute.rhino3d
As mentioned, everything works without any issues from inside the container when I curl against localhost:5000. But, I can't get any response when I try to curl from the host (after running docker run -p nodeport:containerport imagename). I'm not sure if it has something to do with firewall or anything in the Dockerfile is not configured properly.
Any help is appreciated.
By default, the EXPOSE instruction does not expose the container’s ports to be accessible from the host. In other words, it only makes the stated ports available for inter-container interaction.
For example, let’s say you have a Node.js application and a Redis server deployed on the same Docker network. To ensure the Node.js application communicates with the Redis server, the Redis container should expose a port.
If you check the Dockerfile of the official Redis image, a line is included that says EXPOSE 6379. This is what allows the two containers to talk with one another.
Therefore, when your Node.js application connects to the 6379 port of the Redis container, the EXPOSE directive is what ensures the inter-container communication takes place.
you can't publish a port to your host via Dockerfile. you should do that via the docker-compose.yml file or via the command line.
after your image gets built with the Dockerfile then you can use the command below to publish port 5000 of your container to port 5000 of your host.
docker run -it image:tag -p 5000:5000
I suspected the issue might be with "localhost", since it only responds to localhost from inside and it doesn't respond from anywhere else. We added .NET variable ASPNETCORE_URLS to our Dockerfile.
# bind rhino.compute to port 5000
ENV ASPNETCORE_URLS="http://*:5000"
EXPOSE 5000
This will ensure that the application is listening on interfaces, not only localhost and that resolved the issue

Starting a Windows service in a Docker container

I am using Docker for Windows and am trying to convert a Asp.NET MVC 5 to a container. The one remaining roadblock is that I need the ASPNET State server running. I can start up the service through the interactive terminal and it works just fine, but am unable to get the container to start the service automatically. I've tried using CMD, ENTRYPOINT, and RUN, but from what I gather some of these will only execute the command while the image is building, not when the container starts.
My DOCKERFILE is as follows
FROM microsoft/aspnet:4.7.1-windowsservercore-1709
ARG source
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker/publish} .
CMD powershell -Command \
Set-Service aspnet_state automatic; \
Start-Service -name "aspnet_state"; \
EXPOSE 1433
Instead of using CMD, I used RUN to commit the command to the image, and used multiple RUN commands:
# Enable Session State Server
RUN powershell -Command Set-Service aspnet_state -startuptype automatic
RUN powershell -Command Stop-Service aspnet_state
RUN powershell -Command Start-Service aspnet_state
RUN powershell -Command Set-ItemProperty Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters -Name AllowRemoteConnection -Value 1
You simply need the following code after you have properly installed the service into the image.
ENTRYPOINT ["powershell"]
CMD Start-Service \""MyWindowsServiceName\"";
NOTE: The name of a windows service may be different to its executable name. You need the windows service name here, not the executable name.

Start java application without Graphics Environment

I get the following Java exception when I run my application from within docker.
Exception in thread "AWT-EventQueue-0" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204)
at java.awt.Window.<init>(Window.java:536)
at java.awt.Frame.<init>(Frame.java:420)
at java.awt.Frame.<init>(Frame.java:385)
at javax.swing.JFrame.<init>(JFrame.java:189)
at mantra.mfs100.test.MFS100Test.<init>(MFS100Test.java:67)
at mantra.mfs100.test.MFS100Test$8.run(MFS100Test.java:450)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
My docker file looks like this...
# cat Dockerfile
FROM openjdk:8
COPY . /usr/src/myapp
WORKDIR "x64/mfs100_9.0.2.2_x86_redist/"
RUN "./install.sh"
WORKDIR /usr/src/myapp
CMD ["java", "-jar", "/usr/src/myapp/dist/myap.jar"]
I am using Ubuntu Desktop provided by Amazon for testing. If I install the Java Application on Ubuntu desktop (without docker) it works as expected. Is this docker problem or the way I access Amazon cloud ubuntu?
you should set up headless mode, passing java.awt.headless=true, using something like this:
CMD ["java", "-Djava.awt.headless=true", "-jar", "/usr/src/myapp/dist/myap.jar"]
There are multiple ways to do it. The most common way is to share your host X11 display to the docker container
docker run -d \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v /etc/localtime:/etc/localtime \
-e DISPLAY=unix$DISPLAY \
<yourcontainer>
Next as #SimonlucaLandi, suggested you can run a headless version
CMD ["java", "-Djava.awt.headless=true", "-jar", "/usr/src/myapp/dist/myap.jar"]
Below are some more related references that you can refer if you need to go the X11 display version
How to view GUI apps from inside a docker container
X11 forwarding of GUI app in Docker container
https://medium.com/#dimitris.kapanidis/running-gui-apps-in-docker-containers-3bd25efa862a

frequent restart - docker containers in marathon/mesos

I have been successful till completely dockerizing my webserver application. Now I want to explore more by deploying them directly to a mesos slave through marathon framework.
I can deploy a docker container in to a marathon in two different approaches , either command line or through marathon web UI.
Both worked for me but challenge is when I am trying to deploy my docker image, marathon frequently restarting a job and in mesos UI page I can see many finished job for the same container. Close to 10 tasks per minute. Which is not expected I believe.
My docker file looks like below:
FROM ubuntu:latest
#---------- file Author / Maintainer
MAINTAINER "abc"
#---------- update the repository sources list
RUN apt-get update && apt-get install -y \
apache2 \
curl \
openssl \
php5 \
php5-mcrypt \
unzip
#--------- installing composer
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
RUN a2enmod rewrite
#--------- modifying the 000default file
COPY ./ /var/www/airavata-php-gateway
WORKDIR /etc/apache2/sites-available/
RUN sed -i 's/<\/VirtualHost>/<Directory "\/var\/www"> \n AllowOverride All \n <\/Directory> \n <\/VirtualHost>/g' 000-default.conf
RUN sed -i 's/DocumentRoot \/var\/www\/html/DocumentRoot \/var\/www/g' 000-default.conf
WORKDIR /etc/php5/mods-available/
RUN sed -i 's/extension=mcrypt.so/extension=\/usr\/lib\/php5\/20121212\/mcrypt.so/g' mcrypt.ini
WORKDIR /var/www/airavata-php-gateway/
RUN php5enmod mcrypt
#--------- making storage folder writable
RUN chmod -R 777 /var/www/airavata-php-gateway/app/storage
#-------- starting command
CMD ["sh", "-c", "sh pga-setup.sh ; service apache2 restart ; /bin/bash"]
#--------- exposing apache to default port
EXPOSE 80
Now I am clueless how to resolve this issue,any guidance will be highly appreciated.
Thanks
Marathon is meant to run long-running tasks. So in your case, if you start a Docker container that does not keep listening on a specific port, meaning it exits successfully or unsuccessfully, Marathon will start it again.
For example, I started a Docker container using the simplest image hello-world. That generated more than 10 processes in Mesos UI in a matter of seconds! This was expected. Code inside Docker container was executing successfully and exiting normally. And since it exited, Marathon made sure that another instance of the app was started immediately.
On the other hand, when I start an nginx container which keeps listening on port 80, it becomes a long running task and a new task (Docker container) is spun up only when the existing container exits (successfully or unsuccessfully).
You probably need to work on the CMD section of your Dockerfile. Does the container in question keep running when started normally? That is, without Marathon - just using plain docker run? If yes, check if it keeps running in detached mode - docker run -d. If it exits, then CMD is the part you need to work on.

Resources