I have an issue with http-proxy-middleware.
My setup is I have my flask API and my React frontend both in docker containers, run from a docker-compose file.  All works well.  Flask is on localhost:5000 and react on localhost:3000
My Flask API is listening on a route localhost:5000/recent_customers for a POST request.
Using Postman, I can send some info and get a nicely formed JSON response.  It's working well.
The problem is, when I try and use the http-proxy-middleware to call say http://localhost:3000/api/recent_customers which SHOULD route to http://localhost:5000/recent_customers I get the following error:
Error occured while trying to proxy to: localhost:3000/api/recent_customers
With React, I've setup http-proxy-middleware and have the setupProxy.js as such:
  const { createProxyMiddleware } = require("http-proxy-middleware");
  module.exports = function (app) {
    app.use(
      "/api",
      createProxyMiddleware({
        target: "http://localhost:5000",
        changeOrigin: true,
      })
    );
  };
I've setup my Axios as such:
  import axios from "axios";
  const instance = axios.create({
    baseURL: "/api",
  });
  instance.defaults.headers.common["Authorization"] = "AUTH TOKEN FROM INSTANCE";
  // instance.interceptors.request...
  export default instance;
I import the axios into my React component and this is a cropped version of it for clarity:
 import React, { useEffect, useState } from "react";
    import RecentCustomersList from "../../components/Home/RecentCustomerList/RecentCustomerList";
    import axios from "../../axios";
    export default function Home(props) {
    
    // total number of active customers in the system
    const [totalActiveCustomers, setTotalActiveCustomers] = useState(
        "calculating."
    );
    // list of a few customers that have been added recently
    const [recentCustomers, setRecentCustomers] = useState([]);
    
    // This is currently taking temp JSON data.  We will take this from our API with axios in time
    const recentCustomersHandler = () => {
        axios.post("/recent_customers").then((response) => {
        const customers = response.data;
        setRecentCustomers(customers);
        });
    };
    // load the axios API data to be sent to the recent customers
    useEffect(() => {
        recentCustomersHandler();
    }, []);
    // more here for prepping the display of data
    return (
        <div>
        <Grid container spacing={3}>
            {/* more layout here but trimmed for clarity */}
            <RecentCustomerListGridItem />
        </Grid>
        </div>
    );
    }
My React Dockerfile is here:
# Pull official node image
FROM node:14.15.1
# Expose ports.  3000 for web access.  35729 for hot reloading
EXPOSE 3000
EXPOSE 35729
# Set working directory in the docker container
WORKDIR /app
# Add /app/node_modules/.bin to environment variables
ENV PATH /app/node_modules/.bin:$PATH
# Copy package files and install app dependencies
COPY package.json ./app/package.json
COPY package-lock.json ./app/package.json
RUN npm install
RUN npm install react-scripts -g
# Add React app to working directory
ADD . /app
# Start the React app
CMD ["npm", "start"]
My docker-compose file is here:
  version: "3.7"
  services:
    # react
    client:
      container_name: react
      build:
        context: ./frontend
        dockerfile: Dockerfile
      tty: true
      ports:
        - "3000:3000"
      volumes:
        - ./frontend:/app
        - /app/node_modules
      networks:
        - frontend
      depends_on:
        - flask_api
    # flask
    flask_api:
      container_name: flask-api
      build:
        context: ./backend
        dockerfile: Dockerfile
      command: gunicorn --reload --bind 0.0.0.0:5000 flask_api.app:create_app()
      ports:
        - "5000:5000"
      volumes:
        - ./backend:/app #  mount the /backend folder to the docker's /app directory. This allows for hotloading in flask, so when I save locally, container updates
        - appdata:/var/www/
      networks:
        - frontend
        - backend
  networks:
    frontend:
      driver: bridge
    backend:
      driver: bridge
  volumes:
    appdata:
      driver: local
I wonder if anyone is able to spot an issue. If I am missing any info that might help, please do let me know and I'll udpate the question. Thank you.
UPDATE 1 : If I update my axios file to the following:
import axios from "axios";
const instance = axios.create({
  baseURL: "http://localhost:5000",
});
instance.defaults.headers.common["Authorization"] = "AUTH TOKEN FROM INSTANCE";
// instance.interceptors.request...
export default instance;
I still get the same error from Postman, however my console in react / the browser shows as this error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5000/recent_customers. (Reason: CORS request did not succeed).
                        
I was finally able to get this working with a reverse proxy using nginx to host my app.
First you have to use a multistage build with Docker so you can pull in nginx to host your app. Here's a sample Docker config:
There's a few key points in this config:
react-scriptsso I can create a production build of my app within the context of Docker so we can use that output in the second stage. In the second stage, I create an nginx build that hosts my app.nginx.confIn
nginx.conf- that's where you set up the main entry point for your app which serves up your react app. After that, you add a reverse proxy to point to your actual API. Here's my config:location /is the main entry point for your app - that's where you specify that everything routes toindex.html.The juicy part is
location /api- that's the reverse proxy you need to allow your app to communicate via middleware proxy back to your API. In your React app, everything goes to/api/someEndpoint- I created anapi.tsfile to ensure every call is prepended with/api. This is all working excellently for me, the app performs well and calls to my back end are very fast. Hopefully this helps :)