Reach Backend Container API from Frontend Container In Dockerized App reddit / selfhosted ---------------------------------------------------------------------- norsemanGrey · 2023-10-06 11:35 I'm trying to Dockerize an Angular / FastAPI application template where the backend and frontend are in different containers (the Angular app running in an Nginx container and the FastApi using uvicorn). However, I am struggling to get the backend API to work in my frontend without publishing the backend port (which I don't want). The containers are running on the same network and I am *able to access the backend endpoint address from the frontend container*, but any attempt to get it from the Angular application results in either a ERR\_CONNECTION\_REFUSED or a CORS error. I have very little experience with Nginx and backend/frontend communication within Docker, but I have tried a number of variations of the below configs and different combinations of using `localhost` and the backend service name in the address fields. Still I cannot get it to work. I would really appreciate any input and suggestions to make this work. **Frontend API service** import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class ApiService { private endpoint = 'http://localhost:8000/api'; constructor(private http: HttpClient) { } public get(): Observable { return this.http.get(this.endpoint) } } **Frontend Dockerfile** FROM nginx:bookworm RUN rm -rf /usr/share/nginx/html/* COPY nginx.conf /etc/nginx/conf.d/default.conf COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] **Backend API** from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() app.add_middleware(     CORSMiddleware,     allow_origins=["*"],     allow_credentials=True,     allow_methods=["*"],     allow_headers=["*"] ) @app.get("/api") def read_root(): return {"message": "It's working!"} **Backend Dockerfile** FROM base as production COPY --from=builder /app/venv /app/venv COPY --from=builder /app/main.py /app/main.py ENV PATH="/app/venv/bin:$PATH" USER $USERNAME EXPOSE 8000 CMD ["uvicorn", "--reload", "main:app", "--host", "0.0.0.0", "--port", "8000"] **Docker Compose** version: '3.9' networks: app-network: driver: bridge name: app-network services: backend: image: backend:latest container_name: backend-prod networks:       - app-network frontend: image: frontend:latest container_name: frontend-prod depends_on:       - backend networks:       - app-network ports:       - "4200:80" **nginx.conf** server {     listen 80;     location / {         root /usr/share/nginx/html;         try_files $uri $uri/ /index.html;     }      location /api {         proxy_pass http://backend:8000/api;         proxy_set_header X-Forwarded-Host $host;         proxy_set_header X-Forwarded-Server $host;         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;      } } ​ ---------------------------------------------------------------------- thekrautboy · 2023-10-06 11:40 When using Docker networking between containers you dont use localhost, you simply connect by using the containernames as they become automatically hostnames. And you connect to the containers internal service port, not external which you might use for external access. This is more a question for /r/Docker and maybe /r/webdev ---------------------------------------------------------------------- norsemanGrey · 2023-10-06 11:42 As mentioned in the post I have also tried container names and service names. The results have been the same. This might be a Docker config issue, but I think not. ---------------------------------------------------------------------- thekrautboy · 2023-10-06 11:45 > As mentioned in the post I have also tried container names and service names. Yes but you dont mention what names you have tried. One thing i can spot is for example in your compose you set the container_name for backend to `backend-prod` but in your nginx.conf you refer to `http://backend:8000/api` ---------------------------------------------------------------------- zodiacg · 2023-10-06 13:39 irc, in a frontend-backend framework, the "frontend" runs in the browser of the client, so it's the browser trying to access the backend instead of the frontend server. It doesn't matter whether itself can connect to the backend server. Frontend server is just serving static files, as the Dockerfile of the frontend server shows. The backend server must be published, by using a different port number in your case. Or you can host it under a different domain/hostname with any proper reverse proxy. ---------------------------------------------------------------------- norsemanGrey · 2023-10-06 13:46 Yes it is my understanding that you can only call an API using the backend service name from the frontend if it and the backend are running and being accessed within same network. The Angular app and the backend are running in same network, but the Angular app is being accessed from the host machine, not inside container. However, I thought this was what the Nginx was supposed to solve and redirect queries to the backend? ---------------------------------------------------------------------- moojc · 2023-10-06 14:20 I think there's a couple issues here, - Your nginx conf is pointed to `backend` instead of `backend-prod` which is the container name. I would recommend not setting a container name, so it will default to `backend` and then your nginx conf should be able to reach the container via docker network. - Try proxy_pass `Host` in your nginx conf instead of `X-Forwarded- Host`. This should bypass the need for CORS middleware. - If you still want to use the forwarded header, try setting `allow_origins=["*"]` in your backend code. You currently have it to set to a list with an empty string, which I'm pretty sure effectively disables CORS requests. ---------------------------------------------------------------------- zodiacg · 2023-10-06 14:39 I misunderstood the nginx.conf part in the previous comment. If nginx handles the request to the backend and nginx listens on 80, then the Angular app should make requests to "http://localhost/api" instead of "[http://localhost:8000/api](http://localhost:8000/api)". Your Angular app is accessing 8000 and that's why it works when the port of backend container is published. Also, the hostnames of containers are only available inside the docker network. Thus, you cannot access it with nginx from the host machine like what you did in the nginx.conf. However, you can "publish" your backend to [127.0.0.1:](https://127.0.0.1:8000)5588 or any other port by "-p 127.0.0.1:5588:8000". In this case the nginx can access the backend with "localhost:5588", while the port isn't actually "open" to the outer network. ---------------------------------------------------------------------- DanielHilgarth · 2023-10-08 07:36 This is it. There is no Angular application running in the frontend container. The frontend container simply serves the files which will then execute inside the browser of the user, meaning that the request to the behebe API is coming from the browser and not from the frontend container.