So I'm currently building a docker setup with a REST API and a separate frontend. My backend consists of Symfony 5.2.6 as REST API and my frontend is a simple Vue application.
When I try to call my API from the vue application via localhost or 127.0.0.1, I get a "Connection refused" error. When I try to call the API via the external IP of my server, I run into CORS issues. This is my first setup like this, so I'm kind of at a loss.
This is my docker setup:
version: "3.8"
services:
# VUE-JS Instance
client:
build: client
restart: always
logging:
driver: none
volumes:
- ./client:/app
- /app/node_modules
environment:
- CHOKIDAR_USEPOLLING=true
- NODE_ENV=development
ports:
- 8080:8080
# SERVER
php:
build: php-fpm
restart: always
ports:
- "9002:9000"
volumes:
- ./server:/var/www/:cached
- ./logs/symfony:/var/www/var/logs:cached
# WEBSERVER
nginx:
build: nginx
restart: always
ports:
- "80:80"
volumes_from:
- php
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./logs/nginx/:/var/log/nginx:cached
So what is the correct way to establish the connection between those two containers?
The client app runs on port 8080 but nginx on 80 is a different URL and it should be a CORS error.
To avoid it, in the PHP app, you have to add response header:
Access-Control-Allow-Origin: http://localhost:8080 or
Access-Control-Allow-Origin: *.
Another solution is to configure all in one domain on this same port.
Related
I have two containers (both .net-core), a Web Application and a Web API, the Web Application can be accessed from the host machine using http://localhost:51217, however I can't access the Web API using http://localhost:51218, I got the connection refused, in order to access the Web API, I had to change the Kerstel URL configuration from ASPNETCORE_URLS=http://localhost to ASPNETCORE_URLS=http://0.0.0.0, so webserver listen all IP's.
Any clue why the localhost works for the Web App but not for the Web API, although both have different port mapping.
See below my docker-compose working fine, if I change the API to ASPNETCORE_URLS=http://localhost, I will get connection refused. The docker files exposes port 80.
version: '3.5'
services:
documentuploaderAPI:
image: ${DOCKER_REGISTRY-}documentuploader
container_name: DocumentUpoaderAPI
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0
networks:
- doc_manager
ports:
- "51217:80"
volumes:
- ${APPDATA}/Microsoft/UserSecrets/:/root/.microsoft/usersecrets
- ${APPDATA}/ASP.NET/Https/:/root/.aspnet/https/
- c:\azurite:/root/.unistad/
build:
context: .
dockerfile: DocumentUploader/Dockerfile
documentmanagerAPP:
image: ${DOCKER_REGISTRY-}documentmanager
container_name: DocumentManagerApp
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://localhost;http://localhost
networks:
- doc_manager
ports:
- "51218:80"
volumes:
- ${APPDATA}/Microsoft/UserSecrets/:/root/.microsoft/usersecrets
- ${APPDATA}/ASP.NET/Https/:/root/.aspnet/https/
build:
context: .
dockerfile: Document Manager/Dockerfile
networks:
doc_manager:
name: doc_manager
driver: bridge
Any idea why localhost doesn't work for the API? Any suggestion also how can I trace or sniff the communication from browser until the web server in the container?
You can find below the docker networking design, which may help on my question.
my system contains 3 dockers:
mongodb
api backend, built with Nestjs
web application, build with Nuxt.js
the mongo and the backend seems to be working, because i can access the swagger at localhost:3000/api/.
the Nuxtjs web app is failing, and i'm getting 500 Nuxtserver error.
Dockerfile (for the web app):
FROM node:12.13-alpine
ENV APP_ROOT /src
RUN mkdir ${APP_ROOT}
WORKDIR ${APP_ROOT}
ADD . ${APP_ROOT}
RUN npm install
RUN npm run build
ENV HOST 0.0.0.0
EXPOSE 4000
docker-compose.yml:
version: "3"
services:
# backend nestjs app
api:
image: nestjs-api-server
container_name: my-api
depends_on:
- db
restart: unless-stopped
environment:
- NODE_ENV=production
ports:
- 3000:3001
networks:
- mynet
links:
- db
# mongodb
db:
image: mongo
container_name: db_mongo
restart: unless-stopped
volumes:
- ~/data/:/data/db
ports:
- 27017:27017
networks:
- mynet
# front web app, nuxt.js
web:
image: nuxtjs-web-app
container_name: my-web
depends_on:
- api
restart: always
ports:
- 4000:4000
environment:
- BASE_URL=http://localhost:3000/api
command:
"npm run start"
networks:
- mynet
networks:
mynet:
driver: bridge
Looks like the nuxtjs app cannot connect to the api. in the log i see:
ERROR connect ECONNREFUSED 127.0.0.1:3000
But why? the swagger (coming from the same api) works fine on http://localhost:3000/api/#/.
Any idea?
environment:
- BASE_URL=http://localhost:3000/api
localhost in a container means inside that particular container. i.e., it will try to resolve port 3000 in my-web container itself.
Basically from front-end you cannot do container communication. May be you can communicate via public hostname or ip or you can make use of extra_hosts concept in docker-compose to resolve localhost.
Got it. The problem was in nuxtServerInit. This is a very special method on vuex, and it is running in the server. i called $axios from it, and i guess you can't do that.
once i commented that method, it's working fine.
I have a few services running in different docker containers, as per my docker-compose:
version: '3'
services:
rest:
build:
context: './service/'
image: persian_rest:latest
container_name: persian_rest
ports:
- 8080:8080
networks:
- persian_net
volumes:
- persian_volume:/data
scheduler:
build:
context: './scheduler/'
image: persian_scheduler:latest
container_name: persian_scheduler
networks:
- persian_net
ui:
build:
context: './ui/'
image: persian_ui:latest
container_name: persian_ui
ports:
- 5000:5000
networks:
- persian_net
database:
image: 'mongo:latest'
container_name: 'persian_database'
networks:
- persian_net
environment:
- MONGO_INITDB_ROOT_USERNAME=persian_admin
- MONGO_INITDB_ROOT_PASSWORD=123456
ports:
- 27017:27017
volumes:
- persian_volume:/data
volumes:
persian_volume:
networks:
persian_net:
driver: bridge
I have my UI persian_ui service making HTTP request to the REST service persian_rest. I thought that since they were in the same network, I would just make a request to http://persian_rest:8080/api
However, when I do make that request, it fails to find that resource:
Does anyone know why my containers joined by the same network are not able to perform requests?
Currently you are looking at a webpage at localhost:5000. You requested the webpage from the server localhost:5000 and it complied and sent you a webpage which is now sitting on your computer.
If you now want to access an API on the same server as the webpage, you can make another request to localhost but this time port 8080. localhost:8080/api.
The webpage in the browser is on the client-side, and the names you've given your containers are for reference inside the server. From outside the server, currently the reference is localhost.
Hi I'm new to using docker for development. I'm trying to communicate from frontend (react) to the backend (express.js) here.
I have enabled cors as well, I'm getting an error saying net::ERR_NAME_NOT_RESOLVED when trying to fetch from the back end using the url http://backend:4001,
but it's working when I use the docker internal IPAddress, like: http://172.18.0.3:4001.
Following is my docker-compose.yml file.
Please advise on getting this working, thanks.
version: "3"
services:
backend:
build: ./api
volumes:
- ./api:/usr/src/api
ports:
- 6002:4001
depends_on:
- database
database:
image: mongo:4.0.15-xenial
ports:
- 27018:27017
frontend:
build: ./app
volumes:
- ./app:/usr/src/app
ports:
- 6001:3000
links:
- backend
depends_on:
- backend
It will not work, because your browser(internet client) is not part of docker stack network, you have to configure you frontend service to connect to http://localhost:6002 instead of http://backend:4001
I have seen several possibilities how to communicate between docker containers. I tried the most of them except proxying which i cant translate to my scenario.
I have a vue-frontend, java-backend- container.
In the frontend i use axios to make http request.
I want to make a http request axios.get(http:localhost:7080/ping), which gives me status 200 but I dont get an response and some CORS problem.(Which is very strange, because the cors header are present if i use postman for the request)
If i use axios.get(http:container_name:7080/ping) I get some other error
net::ERR_NAME_NOT_RESOLVED.
Other solutions (using nginx) using reverse proxy. Do I need something like this or do I have some other misconfiguration?
My docker-compose looks like this:
services:
backend:
container_name: backend
build: ./backend
volumes:
- xxx
ports:
- 7048:7048
- 7080:7080
- 7009:9009
frontend:
container_name: frontend
build:
context: ../frontend
dockerfile: ./Dockerfile
volumes:
- ../xxx
ports:
- 8080:8080
#- 8001:8001
depends_on:
- backend
environment:
- NODE_ENV=development
# - CHOKIDAR_USEPOLLING=true