1

So I have a docker-compose file with 3 services: backend, react frontend and mongo.

backend Dockerfile:

FROM ubuntu:latest
WORKDIR /backend-server
COPY ./static/ ./static
COPY ./config.yml ./config.yml
COPY ./builds/backend-server_linux ./backend-server
EXPOSE 8080
CMD ["./backend-server"]

frontend Dockerfile:

FROM nginx:stable
WORKDIR /usr/share/nginx/html
COPY ./build .
COPY ./.env .env
EXPOSE 80
CMD  ["sh", "-c", "nginx -g \"daemon off;\""]

So nothing unusual, I guess.

docker-compose.yml:

version: "3"

services:
    mongo-db:
        image: mongo:4.2.0-bionic
        container_name: mongo-db
        volumes:
            - mongo-data:/data
        network_mode: bridge

    backend:
        image: backend-linux:latest
        container_name: backend
        depends_on:
            - mongo-db
        environment:
            - DATABASE_URL=mongodb://mongo-db:27017
            ..etc
        network_mode: bridge
        # networks: 
        #     - mynetwork
        expose:
            - "8080"
        ports:
            - 8080:8080
        links:
            - mongo-db:mongo-db
        restart: always

    frontend:
        image: frontend-linux:latest
        container_name: frontend
        depends_on:
            - backend
        network_mode: bridge
        links:
            - backend:backend
        ports:
            - 80:80
        restart: always

volumes:
    mongo-data:
        driver: local

This is working. My problem is that by adding ports: - 8080:8080 to the backend part, that server becomes available to the host machine. Theoretically the network should work without these lines, as I read it in the docker docs and this question, but if I remove it, the API calls just stop working (but curl calls written in the docker-compose under the frontend service will still work).

alparius
  • 60
  • 8

1 Answers1

1

Your react frontend is making requests from the browser. Hence the endpoint, in this case, your API needs to be accessible to the browser, not the container that is handing out static js, css and html files.

Hope this image makes some sense.

enter image description here

P.S. If you wanted to specifically not expose the API you can get the Web Server to proxy Requests to /api/ to the API container, that will happen at the network level and mean you only need to expose the one server.

I do this by serving my Angular apps out of Nginx and then proxy traffic for /app1/api/* to one container and /app2/api/* to another container etc

  • It makes sense up to the point that I feel ashamed. Thank you for the explanation and for this piece of an art sequence diagram. So this is what proxy-filters are for, if I'm right. – alparius Sep 04 '19 at 16:03
  • Proxies come in many different guises, in its purest form, it's just a go-between. As you have found, there are lots of reasons why you might want to do that. But it generally centers around some case where access is limited, of course in your case it's not even by design just by the fact that the networks are not the same and you don't want to open everything up, completely natural. A Proxy-Filter is a go-between where filtering is applied, either for security reasons, wanting to restrict certain content, block sites, etc. – Jonathan Turnock Sep 04 '19 at 16:12