Cannot access localhost with dockerized app - docker

MacOS Monterey
I have a simple Dockerfile
FROM denoland/deno:1.29.1
EXPOSE 4200
WORKDIR /app
ADD . /app
RUN deno cache ./src/index.ts
CMD ["run", "--allow-net", "--allow-read", "./src/index.ts"]
And the most simple deno code
const handler = (request: Request) => {
return new Response("heyo", { status: 200 });
};
DenoServer.serve(handler, { hostname: HOST, port: PORT });
Running the application locally works fine and I can reach localhost:4200. However when I run the app with docker the request fails
I use
docker run --publish 4200:4200 frontend
└───> curl http://localhost:4200
curl: (52) Empty reply from server
I can see the container running and trying to hit the {{ .NetworkSettings.IPAddress }} doesn't work either
docker container running on localhost

It appears that the necessary environment variables were not included in the docker run command. To specify the host and port, you can use the -e option in the docker command.
docker build -t deno-sample .
docker run -e HOST=localhost -e PORT=4200 -p 4200:4200 deno-sample
For more information, please refer to the Docker documentation at the following link: https://docs.docker.com/engine/reference/commandline/run/
FROM denoland/deno:1.29.1
EXPOSE 4200
WORKDIR /app
COPY . /app
# RUN deno cache ./src/index.ts
RUN ls
CMD ["deno", "run", "--allow-net", "--allow-read", "app.ts"]
Here is my app.ts in same path as of dockerfile
function requestHandler() {
console.log(">>>>>")
return new Response("Hey, I'm a server")
}
serve(requestHandler, { hostname: '0.0.0.0', port: 4200 })

Related

Dockerfile expose 80 port

I am trying to create a simple docker container with go mod and 1.18.
my app runs in 8080 port but i wanna run in :80 port
Dockerfile
FROM golang:1.18
WORKDIR /usr/src/app
# pre-copy/cache go.mod for pre-downloading dependencies and only redownloading them in subsequent builds if they change
COPY go.mod go.sum ./
RUN go mod download && go mod verify
COPY . .
RUN go build -o server
CMD [ "./server" ]
so i run docker build:
docker build -t go-k8s .
and docker run
docker run --rm -p 8080:8080 go-k8s:latest
And nothing happens :(
As larsks says, you need to bind from the external port 80 to the internal port 8080 using the 80:8080 syntax.
Something else to consider is making sure that your app is listening on all interfaces in your development environment.
This question seems at least vaguely related to yours

Problem connecting between containers in Pod

I have a pod with 3 containers in it: client, server, mongodb (MERN)
The pod has a mapped id to the host and the client listens to it -> 8184:3000
The website comes up and is reachable. Server logs says that it has been conented to the mogodb and is listening at port 3001 as I have assigned.
It seems that the client can not connect to the server side and therefor can not check the credentials for login which leads to get wrong pass or user all the time.
The whol program works localy on my windows.
Am I missing some part in docker or crating the pod. As far as I undrstood the containers in a pod should communicate as if they were running in a local network.
This is the gitlab-yml:
stages:
- build
variables:
GIT_SUBMODULE_STRATEGY: recursive
TAG_LATEST: $CI_REGISTERY_IMAGE/$CI_COMMIT_REF_NAME:latest
TAG_COMMIT: $CI_REGISTERY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA
TAG_NAME_Client: gitlab.comp.com/sdx-licence-manager:$CI_COMMIT_REF_NAME-client
TAG_NAME_Server: gitlab.comp.com/semdatex/sdx-licence-manager:$CI_COMMIT_REF_NAME-server
cache:
paths:
- client/node_modules/
- server/node_modules/
build_pod:
tags:
- sdxuser-pod-shell
stage: build
script:
- podman pod rm -f -a
- podman pod create --name lm-pod-$CI_COMMIT_SHORT_SHA -p 8184:3000
build_db:
image: mongo:4.4
tags:
- sdxuser-pod-shell
stage: build
script:
- podman run -dt --pod lm-pod-$CI_COMMIT_SHORT_SHA -v ~/lmdb_volume:/data/db:z --name mongo -d mongo
build_server:
image: node:16.6.1
stage: build
tags:
- sdxuser-pod-shell
script:
- cd server
- podman build -t $TAG_NAME_Server .
- podman run -dt --pod lm-pod-$CI_COMMIT_SHORT_SHA $TAG_NAME_Server
build_client:
image: node:16.6.1
stage: build
tags:
- sdxuser-pod-shell
script:
- cd client
- podman build -t $TAG_NAME_Client .
- podman run -d --pod lm-pod-$CI_COMMIT_SHORT_SHA $TAG_NAME_Client
Docker File Server:
FROM docker.io/library/node:16.6.1
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . ./
EXPOSE 3001
CMD [ "npm", "run", "start" ]
Docker File Client:
FROM docker.io/library/node:16.6.1
WORKDIR /app
COPY package*.json ./
RUN npm install
RUN npm install -g npm#7.21.0
COPY . ./
EXPOSE 3000
# start app
CMD [ "npm", "run", "start" ]
snippet from index.js at clientside trying to reach the server side checking log in credentials:
function Login(props) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
async function loginUser(credentials) {
return fetch('http://127.0.0.1:3001/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(credentials),
})
.then((data) => data.json());
}
}
pod:
Actually it has nothing to do with podman. Sorry about that. I added a proxy to my package.json and it redirected the requests correctly:
"proxy": "http://localhost:3001"

ASP.NET Core + Docker not accessible on specified port

It is impossible for me to access container with ASP.NET Core 3.1 application running inside.
Goal is to run application in container on port 5000. When I'm running it locally using standard VS profile I navigate to http://localhost:5000/swagger/index.html in order to load swaggerUI. I would like to achieve same thing using docker.
Steps to reproduce my issue:
Add dockerfile with exposed 5000 port and ENV ASPNETCORE_URLS variable:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
ENV ASPNETCORE_URLS=http://+:5000
EXPOSE 5000
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["myapp/myapp.csproj", "myapp/"]
RUN dotnet restore "myapp/myapp.csproj"
COPY . .
WORKDIR "/src/myapp/"
RUN dotnet build "myapp.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "myapp.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "myapp.dll"]
Build image
docker build -t myapp .
Run docker image:
docker run myapp -p 5000:5000
Running commands above with specific docker file results in this:
[21:28:42 INF] Starting host.
[21:28:42 INF] Now listening on: http://[::]:5000
[21:28:42 INF] Application started. Press Ctrl+C to shut down.
[21:28:42 INF] Hosting environment: Production
[21:28:42 INF] Content root path: /app
However, I can't access container using http://localhost:5000/swagger/index.html because of ERR_CONNECTION_REFUSED -> This site can't be reached.
I did get into container to check if host is running for sure, using:
docker exec -it containerId /bin/bash
cd /app
dotnet myapp.dll
what resulted in following error:
Unable to start Kestrel.
System.IO.IOException: Failed to bind to address http://[::]:5000: address already in use.
Conclusion is that port inside the container is used, application is alive, it's just not accessible from outside.I don't know how to get inside of it.
Please point me into right direction.
UPDATE
Issue is solved, answer is posted below. However explanation why it was needed and how it works would be nice!
To solve the issue I had to manually add "--server.urls" to entrypoint like shown below:
ENTRYPOINT ["dotnet", "myapp.dll", "--server.urls", "https://+:5000"]
I solved the same issue in the following way:
Added the following in appsettings.json to force Kestrel to listen to port 80.
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://+:80"
}
}
}
Exposed the port in dockerfile
ENV ASPNETCORE_URLS=http://+:80
EXPOSE 80
ENTRYPOINT ["dotnet", "EntryPoint.dll"]
Ran the container using the below command.
docker run -p 8080:80 <image-name>:<tag>
The app exposed on http://localhost:8080/

dial tcp 127.0.0.1:8000: connect: connection refused golang docker containers

I am trying to make an http request from one project to another both using GO. The project that is making the request has the following dockerfile:
FROM golang:alpine as builder
WORKDIR /build
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o main .
FROM scratch
WORKDIR /app
COPY --from=builder /build .
CMD ["./main"]
The project that is waiting for the request is running on localhost:8000 and it has the following dockerfile:
FROM golang:1.13.8 AS build-env
ADD . /dockerdev
WORKDIR /dockerdev
RUN go get -d -v ./...
RUN go build -o /server
# Final stage
FROM debian:buster
EXPOSE 8000
WORKDIR /
COPY --from=build-env /server /
CMD ["/server"]
When I make
resp, err := http.Post("http://localhost:8000/orders", "application/json", bytes.NewBuffer(requestBody))
it gives me the following error
dial tcp 127.0.0.1:8000: connect: connection refused
I am new to docker so any improvements are welcome!
Expanding on my comment. Your client code's network address will not work:
resp, err := http.Post("http://localhost:8000/orders", "application/json", bytes.NewBuffer(requestBody)) // broken
as it is literally talking to itself (localhost refer to the client docker container - not the host OS).
The quickest way - for testing purposes - to expose the two containers to your host OS would be like so:
docker run -it --rm -p 8000:8000 dockweb # server container
docker run -it --rm --net host dockcli # client container
Beyond trivial testing, this can quickly get unwieldy. So I recommend using things like docker-compose which allows you to trivially link containers and their networks.
Try using 0.0.0.0 instead of localhost. This should resolve the connection refused error.

Cannot connect to local Docker running Kestrel server

I have a Kestrel server that returns Hello World to any HTTP request.
static class Program
{
static void Main(string[] args)
{
var webHostBuilder = WebHost.CreateDefaultBuilder(args)
.UseSetting("applicationName", "Hello World")
.Configure(builder => {
builder.Run(async context =>
{
var textBytes = UTF8.GetBytes("Hello World!");
await context.Response.Body.WriteAsync(textBytes, 0, textBytes.Length, default (CancellationToken));
});
})
.UseUrls("http://+:8000");
var webHost = webHostBuilder.Build();
webHost.Run();
}
}
I've added the build assemblies to a Docker image and built it with this DockerFile:
FROM microsoft/dotnet
WORKDIR /app
ADD /application /app
EXPOSE 8000
ENTRYPOINT [ "dotnet", "hello-world-server.dll" ]
I've run it with this:
>docker run hello-world-server --publish-list 8000:8000
When I send a request to http://localhost:8000 I get a 502 returned.
I'm using Windows containers on Windows 10.
The full output from a build & run is below:
C:\...\hello-world-server-docker>docker build -t hello-world-server .
Sending build context to Docker daemon 84.99kB
Step 1/5 : FROM microsoft/dotnet
---> d08db1d19023
Step 2/5 : WORKDIR /app
Removing intermediate container 873dea47b78b
---> de4b80a52d54
Step 3/5 : ADD /application /app
---> ba75fe5b5efc
Step 4/5 : EXPOSE 8000
---> Running in 1ac9c977c9b4
Removing intermediate container 1ac9c977c9b4
---> 22cb3848d762
Step 5/5 : ENTRYPOINT [ "dotnet", "hello-world-server.dll" ]
---> Running in 17f3b01f6ed0
Removing intermediate container 17f3b01f6ed0
---> 82c7e3aadfc2
Successfully built 82c7e3aadfc2
Successfully tagged hello-world-server:latest
C:\...\hello-world-server-docker>docker run hello-world-server --publish-list 8000:8000
Hosting environment: Production
Content root path: C:\app
Now listening on: http://[::]:8000
Application started. Press Ctrl+C to shut down.
When a request is made to localhost:8000 there's no further output on the console from Kestrel, whereas there usually would be is this were a normal console application.
I've also tried running it with >docker run hello-world-server --publish 8000:8000.
I think the problem is in the docker run command. --publish-list 8000:8000 as it is right now, is a parameter for the containers entrypoint.
The command to run a container and expose a port is:
docker run -p 8000:8000 hello-world-server
Every command line option for docker run must be placed before the image name. Everything after the image name is a command for the container itself.

Resources