Unable to access Dockerized Angular application in container [duplicate] - node.js

This question already has answers here:
Cannot connect to exposed port of container started with docker-compose on Windows
(4 answers)
Closed 1 year ago.
Dockerfile:
FROM node:current-alpine3.10
RUN mkdir -p /dist/angular
WORKDIR /dist/angular
COPY package.json .
RUN npm install --legacy-peer-deps
COPY . .
EXPOSE 8500
CMD ["npm","run","start:stage-ena-sso"]
package.json:
...
"scripts": {
"start:stage-ena-sso": "ng serve -o -c=stage-ena-sso --port=8500 --baseHref=/"
}...
Folder structure:
Command used to build the Docker image:
docker build . -t ssoadminuiapp
Command used to run the Docker image:
docker run --rm -it -p 8500:8500/tcp ssoadminuiapp:latest
Check if container is running:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8959e5180eba ssoadminuiapp:latest "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 0.0.0.0:8500->8500/tcp recursing_fermat
But accessing localhost:8500 doesnt seem to work:
I'm really new to Docker, so any useful beginner-friendly tips/infos would be very appreciated.
Edit #1, this is the result after running docker run command:

This is the problem:
Angular Live Development Server is listening on localhost:8500
Because your application is bound to localhost inside the container,
the port isn't available for port forwarding. That's like trying to
run a service on your host bound to localhost -- you can reach it
locally, but nothing remote can connect to it (and from a network
perspective, you host is "remote" from the container).
You'll need to configure the Angular server to bind to all addresses
in the container (0.0.0.0). I'm not sure exactly how to do this in
your application; when running ng serve from the command line there
is a --host option to set the bind address.

Related

Docker and Node .mjs files

I have an express application with all the JS files using the *.mjs extension.
So, to start the server I do node index.mjs and it works as expected.
Now I'm trying to containerize the app.
I have this basic Dockerfile
FROM mhart/alpine-node:14
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
CMD node index.mjs
EXPOSE 80
After building (with no errors) and tagging I try to run my application (docker run my-app:latest) it breaks the line in the console but I don't see the console logs of my server.
If I try to hit localhost at port 80, it doesn't work.
I check the containers with docker container ls and I see the container
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce7ca2a0db96 my-app:latest "/bin/sh -c 'node in…" 6 minutes ago Up 6 minutes 80/tcp clever_bhabha
If I look for logs, nothing.
Does anyone have this issue? Could it be related to .mjs files? If so, is there a way to use them in Docker?
Thanks
I think you need to expose a port different to 80 locally. You should try
docker run -p 8080:80 my-app
Then in localhost:8080 you should reach your app.

On what PORT is my docker container with a React app running? Reacts' default PORT or EXPOSE from Dockerfile?

I'm a newbie to Docker so please correct me if anything I'm stating is wrong.
I created a React app and wrote a following Dockerfile in the root repository:
# pull official base image
FROM node:latest
# A directory within the virtualized Docker environment
# Becomes more relevant when using Docker Compose later
WORKDIR /usr/src/app
# Copies package.json and package-lock.json to Docker environment
COPY package*.json ./
# Installs all node packages
RUN npm install
# Copies everything over to Docker environment
COPY . .
# Uses port which is used by the actual application
EXPOSE 8080
# Finally runs the application
CMD [ "npm", "start" ]
My goal is to run the docker image in a way, that I can open the React app in my browser (with localhost).
Since in the Dockerfile I'm Exposing the app to the PORT: 8080. I thought I can run:
docker run -p 8080:8080 -t <name of the docker image>
But apparently the application is accessible through 3000 in the container, cause when I run:
docker run -p 8080:3000 -t <name of the docker image>
I can access it with localhost:8080.
What's the point of the EXPOSE port in the Dockerfile, when the service running in its container is accessible through a different port?
When containerizing a NodeJS app, do I always have to make sure that process.env.PORT in my app is the same as the EXPOSE in the Dockerfile?
EXPOSE is for telling docker what ports from inside the application can be exposed. It doesn't mean anything if you do not use those port inside (container -> host).
The EXPOSE is very handy when using docker run -P -t <name of the docker image> (-P capital P) to let Docker automatically publish all the exposed ports to random ports on the host (try it out. then run docker ps or docker inspect <containerId> and checking the output).
So if your web Server (React app) is running on port 3000 (inside the container) you should EXPOSE 3000 (instead of 8080) to properly integrate with the Docker API.
It's kind of weird.
Its just documentation in a sense.
https://docs.docker.com/engine/reference/builder/#:~:text=The%20EXPOSE%20instruction%20informs%20Docker,not%20actually%20publish%20the%20port.
The EXPOSE instruction does not actually publish the port. It
functions as a type of documentation between the person who builds the
image and the person who runs the container, about which ports are
intended to be published. To actually publish the port when running
the container, use the -p flag on docker run to publish and map one or
more ports, or the -P flag to publish all exposed ports and map them
to high-order ports.
do I always have to make sure that process.env.PORT in my app is the
same as the EXPOSE in the Dockerfile?
Yes. You should.
And then you also need to make sure that port actually gets published, when you use the docker run command or in your docker-compose.yml file, or however you plan on running docker.
Actually react app runs the default port 3000. so you must to mention ports and expose in docker-compose.yml. Now I'm changing the 3000 port to 8081
frontend:
container_name: frontend
build:
context: ./frontend/app
dockerfile: ../Dockerfile
volumes:
- ./frontend/app:/home/devops/frontend/app
- /home/devops/frontend/app/node_modules
ports:
- "8081:3000"
expose:
- 8081
command: ["npm", "start"]
restart: always
stdin_open: true
And run the docker
$ sudo docker-compose up -d
Then check the running containers for find the running port
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83b970baf16d devops_frontend "docker-entrypoint..." 31 seconds ago Up 30 seconds 8081/tcp, 0.0.0.0:8081->3000/tcp frontend
It's resolved. check your public port
$ curl 'http://0.0.0.0:8081'

Containerized NodeJS application on podman not reachable

I'm running a nodejs app in a pod (together with a mongo container)
Nodejs app listens on port 3000, which I expose from the container.
I have published port 3000 on the pod.
The container starts successfully (logs verified), but I can't reach my application on the host. When I curl to my app from within the pod it works.
Containers run rootfull, OS: CentOS Linux release 8.0.1905 (Core).
What am I missing?
curl http://localhost:3000
curl: (7) Failed to connect to localhost port 3000: No route to host
podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
30da37306acf registry.gitlab.com/xxx/switchboard:master node main.js 34 minutes ago Up 34 minutes ago 0.0.0.0:3000->3000/tcp switchboard-app
acc08c71147b docker.io/library/mongo:latest mongod 35 minutes ago Up 35 minutes ago 0.0.0.0:3000->3000/tcp switchboard-mongo
podman port switchboard-app
3000/tcp -> 0.0.0.0:3000
app.listen(3000, "0.0.0.0",function () {
console.log('App is listening on port 3000!');
});
FROM node:13
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY /dist/apps/switchboard .
EXPOSE 3000
CMD [ "node", "main.js" ]
If you want to create production docker build, you can go another way. It's not a good idea to do npm install inside container, because it will be too large. Run npm run build first, and then copy builded statics into docker container, created with nginx image.
So your Dockerfile shoud look like:
FROM nginx:1.13.0-alpine
COPY build/* /usr/share/nginx/html/
also specify exposed ports correctly with docker run. So, if you want expose 3000, your steps is:
cd /project/dir
docker build -t switchboard-app .
docker run -d -p 3000:80 --name switchboard-app switchboard-app

Unable to reach angular running in Docker container [duplicate]

This question already has answers here:
ng serve not working in Docker container
(7 answers)
Closed 2 years ago.
I am brand new to Docker so pleas bear with me.
Dockerfile:
FROM node:alpine
WORKDIR '/app'
COPY ./package.json .
EXPOSE 4200
RUN npm i
COPY . .
CMD ["npm","start"]
Commands:
docker build -t angu .
docker run -p 4300:4200 angu
I am not sure if I need to include EXPOSE 4200 in Dockerfile. But it is not working either ways.
Your server inside the container is listening on localhost which is different from the localhost on your machine. The container has its own localhost.
To change the app to listen to outside traffic you need to add --host 0.0.0.0 to the ng serve command in the npm start script in package.json like so:
"start": "ng server --host 0.0.0.0"
You don't need to add EXPOSE in your Dockerfile since it doesn't do much practically, it's mostly for documentation purposes. You're already publishing the port with --p. You can read more about this in this article

Run node Docker without port mapping

I am very to new Docker so please pardon me if this this is a very silly question. Googling hasn't really produced anything I am looking for. I have a very simple Dockerfile which looks like the following
FROM node:9.6.1
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /usr/src/app/package.json
RUN npm install --silent
COPY . /usr/src/app
RUN npm start
EXPOSE 8000
In the container the app is running on port 8000. Is it possible to access port 8000 without the -p 8000:8000? I just want to be able to do
docker run imageName
and access the app on my browser on localhost:8000
By default, when you create a container, it does not publish any of its ports to the outside world. To make a port available to services outside of Docker, or to Docker containers which are not connected to the container’s network, use the ‍‍--publish or -p flag. This creates a firewall rule which maps a container port to a port on the Docker host.
Read more: Container networking - Published ports
But you can use docker-compose to set config and run your docker images easily.
First installing the docker-compose. Install Docker Compose
Second create docker-compose.yml beside the Dockerfile and copy this code on them
version: '3'
services:
web:
build: .
ports:
- "8000:8000"
Now you can start your docker with this command
docker-compose up
If you want to run your services in the background, you can pass the ‍‍-d flag (for “detached” mode) to docker-compose up -d and use `docker-compose ps to see what is currently running.
Docker Compose Tutorial
Old question but someone might find it useful:
First get the IP of the docker container by running
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
Then connect to it from the the browser or using curl using the IP and port exposed :
Note that you will not be able to access the container on 0.0.0.0 because port is not mapped

Resources