I'm getting this value on the PORTS column of a docker container ls entry (a container for a react app served by Nginx):
PORTS
80/tcp, 0.0.0.0:40000->40000/tcp, :::40000->40000/tcp
I know the second part is IPv4 mapping and the third is IPv6. I don't understand the meaning of the 80/tcp, but I think it's what really makes the app accessible from the internet, because if I use mapping "80:80" it works, but now with "40000:40000" it doesn't.
My project has a structure like this, so it can build multiple projects at once with compose:
|
|- client (a React app)
| |- Dockerfile-client
|- .env.prod
|- docker-compose.yml
The docker-compose.yml looks like this:
version: '3.7'
services:
client:
build:
dockerfile: ./client/Dockerfile-client
context: ./ # so the .env.prod file can be used by React
container_name: client
env_file:
- .env.prod # enabled to apply CLIENT_PORT var to Dockerfile-client
ports:
- "${CLIENT_PORT}:${CLIENT_PORT}"
# others
All the variables are defined in .env.prod (CLIENT_PORT is 40000), and I run compose like `docker compose --env-file .env.prod up", and it doesn't bring errors.
Here's the Dockerfile that builds the client container:
# build env
FROM node:13.13-alpine as build
WORKDIR /app
COPY ./client/package*.json ./
RUN npm ci
COPY ./client/ ./
COPY ./.env.prod ./
RUN mv ./.env.prod ./.env
RUN npm run build
# production env
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE ${CLIENT_PORT}
CMD ["nginx", "-g", "daemon off;"]
It would all work fine if I mapped "80:80", but my problem is how is that 80/tcp there in the ls output when there's no "80" to be seen in the files? Might it be because of Nginx?
80/tcp is from nginx which listens by default on this port.
Correct port mapping in this case will be 4000:80
OR
If you want nginx to listen on other port like 4000 update listen parameter in nginx.conf file to that port
http {
server {
listen 4000;
}
}
And then use port mapping as 4000:4000
Related
I already have a vue application containerized and running, but how do I put it in docker compose?
Dockerfile:
FROM node:14
WORKDIR /app
RUN npm install #babel/core #babel/node #babel/preset-env nodemon express axios cors mongodb
COPY . .
EXPOSE 4200
CMD ["npm", "run", "serve"]
So when I try to put port "4200" it says that I have already the same port running, so how do I put that container inside whole app which will store multiple containers?
This is my docker-compose try:
version: '3.8'
services:
posts:
build: ./posts
ports:
- "4200:4200"
So this is the visualisation of something that I want to do:
Change host port in compose
For example:
ports:
- "4201:4200"
I've run into a problem where my Docker file is running fine outside of Docker compose, but when used in Docker Compose, my Nginx target isn't installed properly in /usr/share/nginx/html.
docker-compose.yml
version: "3.7"
services:
web:
build:
context: ./web
dockerfile: Dockerfile-development
volumes:
- ./web:/web
- ./web/node_modules/
env_file:
- .env-web
nginx:
build:
context: ./web
dockerfile: Dockerfile-development
target: nginx
volumes:
- ./web/nginx/default.conf:/etc/nginx/conf.d
- ./web/build:/usr/share/nginx/html
ports:
- "80:80"
depends_on:
- web
dockerfile-development
FROM node:9.8.0 as web
ARG APP_ENV=development
WORKDIR /web
COPY package.json /web/package.json
RUN npm install
COPY . /web
RUN npm run build-development
FROM nginx:1.14 as nginx
COPY --from=web /web/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
So if I build and run Dockerfile-development outside of Docker compose everything works and Nginx starts, but if I use docker-compose up the images are built and run without errors, but nginx is no where to be found in the container.
EDIT
I've figured out that the problem lies in build-development which runs webpack --watch. It results nginx not running at all. Any way I can have both webpack with the watch flag run in the background, and still have docker move on to building and running the nginx container?
I have built a docker-compose file for my node js application that has been dockerized, But I don't know how to make the API call to that node js app which is running as a docker container, Please help me with this concern.
My DockerFile:
FROM node:10.15-slim
ENV NODE_ENV=production
WORKDIR /app
COPY package.json package-lock*.json ./
RUN npm install && npm cache clean --force
COPY . .
CMD ["node", "./bin/www"]
My Docker-compose file:
version: '2.4'
services:
express:
build:
context: .
dockerfile: Dockerfile
command: /app/node_modules/.bin/nodemon ./bin/www
ports:
- 3000:3000
volumes:
- .:/app
environment:
- DEBUG=sample-express:*
- NODE_ENV=development
You'll need to expose the port from docker on which your application is running.
Let's say your application is running on port 8080 inside docker, here's how you can expose that specific port:
EXPOSE 8080
Then you'll need to map the port exposed by docker tthato your local port. Here's how you can do it in docker:
docker run -p 49160:8080 -d docker_image
And if you're working with docker-compose, you'll do it like this:
version: '3'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
ports:
- "8080:8080"
UPDATE
Let's say you want to send /api requests to back-end server. This is how you'll do it in nginx conf:
server {
listen 80
location /api {
proxy_pass http://backend:8080/;
}
}
I hope it helps.
I'm having the .Dockerfile (from the source):
# build stage
FROM node:9.11.1-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# production stage
FROM nginx:1.13.12-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Where at the end the application is exposed to port 80. I'm then having another different .Dockerfile and for building both of them I'm using the following docker-compose.yml file:
version: "3"
services:
service-name-one:
image: dockerImageFromAbove
ports:
- "8080:80"
service-name-two:
image: someOtherImage
ports:
- "3000:3001"
And this is the example that is actually working. But I would need to change the port from nginx docker image and instead of port 80 I would need to have port 8081. By simple changing this in both files from above, it's not working and in my research I found that the only working example is when exposing to port 80 from nginx.
I tried replacing the line
EXPOSE 8081
with
RUN -P 80:8081
EXPOSE 8081
but seems as -P flag is not supported here. So how can I do such a mapping, before exposing nginx to port 80?
I found this post, but I can't figure out how to use the answers in my docker files.
I also found this post (part for environment variables), but also not sure how to integrate it with my docker-compose file.
The second file is not a Dockerfile but a docker-compose.yml, you have to change in the docker-compose.yml the ports and it will be ok.
The option -p "hostport:containerport" expose the port when you use command docker run.
Anyway i suggest you to use the supported and official image before change too much the Image in the dockerfile.
Anyway if you really need 8081 try something like this
version: "3"
services:
service-name-one:
image: yournginxOrSomethingelse
ports:
- "8080:80"
- "8085:8081"
I believe -P needs to be lower case: -p (this is for command-line command, not Dockerfile) The syntax is:
Dockerfile:
....
EXPOSE 80
....
Command line:
docker run -d -p 8081:80 --name my-service my-service:latest
I am trying to use jwilder/nginx-proxy as a reverse proxy for my angular2 app that is broken down into 3 containers (angular, express and database).
I have tried different configurations to proxy requests to my app on port 80, however when I try to run docker-compose I get :
ERROR: for angular Cannot start service angular: driver failed programming
external connectivity on endpoint example_angular_1
(335ce6d0c775b7837eb436fff97bbb56bfdcaece22d51049e1eb4bf5ce45553c): Bind for
0.0.0.0:80 failed: port is already allocated
While the message is pretty clear that there is a conflict on port 80, I cannot figure out a way to go around it, it works just fine when I set my angular container to work on port 4200 but then I have to specify the port number in url every time I want to visit the page. I am using the reverse proxy because it is not the only app that will be running in my environment
Below is my docker-compose.yml
version: '3'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports: - "80:80"
volumes: - /var/run/docker.sock:/tmp/docker.sock:ro
angular:
build: client
ports: - "80"
environment:
- VIRTUAL_HOST=example.com
- VIRTUAL_PORT=80
restart: always
express:
build: server
ports: - "3000:3000"
links: - database
restart: always
database:
image: mongo
ports: - "27017:27017"
restart: always
networks:
default:
external:
name: nginx-proxy
And Dockerfile for the angular container
FROM node:8-alpine as builder
COPY package.json package-lock.json ./
RUN npm set progress=false && npm config set depth 0 && npm cache clean --force
RUN npm i && mkdir /ng-app && cp -R ./node_modules ./ng-app
WORKDIR /ng-app
COPY . .
RUN $(npm bin)/ng build --prod --build-optimizer
FROM nginx:1.13.3-alpine
COPY nginx/default.conf /etc/nginx/conf.d/
RUN rm -rf /usr/share/nginx/html/*
COPY --from=builder /ng-app/dist /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
EXPOSE 80
The problems is that you're trying to open the port 80 on the host twice. Once for the nginx-proxy and once for angular. Remove the "ports 80" from angular.
The browser will speak to the container on the virtual_port that you set.
Maybe you can direct the the request to the backend through an api endpoint
If you want to use nginx as a reverse proxy, you need to access to it using the 80 port. Then modify the nginx config to redirect to your angular container and port (81 for example). Try this: "proxy_pass http://angular:81". This should work.