4

I am trying to deploy a Vue app in the frontend and the .net core api in the backend. Using docker-compose file I have been to able to spin up the network and containers but I am struggling to have them communicate. I am pretty new to docker however, do understand that the Vue app dockerfile uses an Nginx base to feed the web app but it seems that may be affecting the network communication as the frontend container does not resolve the backend container name though it should since they are in the same virtual private network with the default bridge driver. When executing a bash shell in the frontend container and doing a curl to the backend container, I do get the correct response.

I did try to expose the backend container to the host and then use the server IP to reach it from the frontend and that does work however, I was hoping to not have to expose my api this way and wanted to make it work through the docker virtual private network if possible.

Example url I am trying in the frontend which encounters a name not resolved error: littlepiggy-api/api or littlepiggy-api:5000/api

Frontend Dockerfile

FROM node:14.18-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./ .
RUN npm run build

# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Backend Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 5000

FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["LittlePiggy.Api/LittlePiggy.Api.csproj", "LittlePiggy.Api/"]
RUN dotnet restore "LittlePiggy.Api/LittlePiggy.Api.csproj"
COPY . .
WORKDIR "/src/LittlePiggy.Api"
RUN dotnet build "LittlePiggy.Api.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "LittlePiggy.Api.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "LittlePiggy.Api.dll"] 

Docker-compose file

version: '3'
services:

  front:
    container_name: littlepiggy-front
    image: josh898/angie-app-front:latest
    ports:
      - 80:80
    networks:
      - littlepiggy
    depends_on:
      - api

  api:
    container_name: littlepiggy-api
    image: josh898/angie-app-backend:latest
    networks:
      - littlepiggy

networks:
  littlepiggy:
    driver: bridge
3
  • The Vue application runs in your browser, not in a container. (The front container runs an Nginx server that serves the application as static files but doesn't run the application itself.) Since it's in the browser and outside of Docker, it can't use Docker networking; you need to connect to one of the published ports: of one of the services. Commented Jan 4, 2022 at 19:21
  • Understood, in that case it would be necessary to expose the api. Maybe I can find a way to restrict the access to the port to only be from that container. Either way I would need to get a certificate for the backend. Thanks for the help Commented Jan 4, 2022 at 19:43
  • The request isn't coming from a container, it's coming from a Javascript application running in a browser. Configuring the Nginx proxy to forward API requests as @HansKilian suggests is a good approach here (it also helps solve CORS problems and trouble around identifying the correct server hostname). Commented Jan 4, 2022 at 19:52

1 Answer 1

4

You need to configure Nginx to pass requests that match the /api route on to the backend service.

If you create a nginx configuration file like this, called nginx.conf and place it in your frontend directory

server { 
    listen 80;

    location / {
        index index.html;
        root /usr/share/nginx/html;
        try_files $uri $uri/ $uri.html =404;
    }

    location /api/ {
        proxy_pass http://littlepiggy-api/;
    }
}

Then copy it into your frontend container by changing your frontend Dockerfile to

FROM node:14.18-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./ .
RUN npm run build

# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Then requests to http://localhost/api/xxxx should be passed on to the backend and requests to http://localhost/index.html should be served by the Nginx container directly.

Sign up to request clarification or add additional context in comments.

1 Comment

Ok that should work thanks. Since I have a domain and it has an SSL certificate it wont allow http. I will probably have to add a certificate the backend. I thought by using the private network that would not be a problem but it seems it is.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.