问题
I have 2 microservices: frontend with next.js and a backend with node.js from where I fetch data via REST-APIs from the frontend.
I now have the problem, that my 2 services don't seem to communicate directly to eachother, the thing is, it works when I fetch the data at the beginnning with the getinitialProps() Method with the fetch-API. My server-side frontend finds the backend via its service-name. However, when I am doing a http-request from the client to the backend (e.g via browser form inputs). It cannot find the backend anymore? Why is that?
here is my docker-compose.yml:
version: '3'
services:
dcbackend:
container_name: dcbackend
build:
context: ./dcbackend
dockerfile: Dockerfile
image: dcbackend
hostname: dcbackend
ports:
- '7766:7766'
dcfrontend:
container_name: dcfrontend
build:
context: ./dcfrontend
dockerfile: Dockerfile
image: dcfrontend
volumes:
- /app/node_modules
- ./dcfrontend:/app
hostname: dcfrontend
ports:
- '6677:6677'
Here is one of my browser-client side methods to send data to the backend (via the browser, my url is http:dcbackend... so normally it should find the other docker environment where the backend is, but it does not...
if (environment == 'dev') {
url_link = `http://localhost:${port}`;
} else {
url_link = `http://dcbackend:${port}`;
}
let doublettenListe_link = `${url_link}/doubletten/`;
finishDocumentHandler = (anzeige,index) => {
let thisDocumentID = anzeige.id;
const requestOptions = {
method: 'PUT'
};
fetch(doublettenListe_link + thisDocumentID, requestOptions)
.then((response) => {
this.setState({finishSuccess: 'Dubletten in Datenbank eintragen erfolgreich!'});
this.setState({finishFail: ''});
this.processDocumentArray(index);
console.log(response);
})
.catch((error) => {
this.setState({finishSuccess: ''});
this.setState({finishFail : `Error beim Erzeugen des Eintrags! Eintrag wurde nicht in Datenbank gespeichert. Bitte prüfen, ob der Server läuft. ${error}`});
});
}
Response from network tab from my request is:
Request URL: http://dcbackend:7766/doubletten/304699981
Referrer Policy: no-referrer-when-downgrade
Provisional headers are shown
Access-Control-Request-Method: PUT
Origin: http://localhost:6677
Referer: http://localhost:6677/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
does it have something to do with docker-configuration, or with CORS() or with anything else? I can't do a client http request to backend, however, the initial fetch from the backend to get some data works...
回答1:
You have to separate the server side and the client side requests. You need to use your host address for the client side requests (eg. http://localhost:7766), because your browser will not be able to reach the backend via docker alias.
You can define the server-only and public runtime config with next.config.js
.
For example:
// next.config.js
module.exports = {
serverRuntimeConfig: {
// Will only be available on the server side
apiUrl: 'http://dcbackend:7766'
},
publicRuntimeConfig: {
// Will be available on both server and client
apiUrl: 'http://localhost:7766'
}
}
Then you need get the apiUrl
from nextjs with getConfig()
// pages/index.js
import getConfig from 'next/config';
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();
const apiUrl = serverRuntimeConfig.apiUrl || publicRuntimeConfig.apiUrl;
const Index = ({ json }) => <div>Index</div>;
Index.getInitialProps = async () => {
try {
const res = await fetch(`${apiUrl}/doubletten/304699981`);
const json = await res.json();
return { json };
} catch(e) {
console.log('Failed to fetch', e);
return { json: null };
}
}
export default Index;
来源:https://stackoverflow.com/questions/55922397/docker-compose-make-2-microservices-frontendbackend-communicate-to-each-other