How to route all traffic from a container through another container in the same Kubernetes pod?

I’m creating a web application that comprises a React frontend and a node.js (express) server. The frontend makes an internal api call to the express server and the express server then makes an external api call to gather some data. The frontend and the server are in different containers within the same Kubernetes pod.

The frontend service is an nginx:1.14.0-alpine image. The static files are built (npm build) in a CI pipeline and the build directory is copied to the image during docker build. The package.json contains a proxy key, "proxy": "http://localhost:8080", that routes traffic from the app to localhost:8080 – which is the port that the express server is listening on for an internal api call. I think the proxy key will have no bearing once the files are packaged into static files and served up onto an nginx image?

When running locally, i.e. running npm start instead of npm build, this all works. The express server picks up the api requests sent out by the frontend on port 8080.

The express server is a simple service that adds authentication to the api call that the frontend makes, that is all. But the authentication relies on secrets as environment variables, making them incompatible with React. The server is started by running node server.js; locally the server service successfully listens (app.listen(8080))to the api calls from the React frontend, adds some authentication to the request, then makes the the request to the external api and passes the response back to the frontend once it is received.

In production, in a Kubernetes pod, things aren’t so simple. The traffic from the React frontend proxying through the node server needs to be handled by kubernetes now, and I haven’t been able to figure it out.

It may be important to note that there are no circumstances in which the frontend will make any external api calls directly, they will all go through the server.

React frontend Dockerfile

FROM nginx:1.14.0-alpine

# Copy static files
COPY client/build/ /usr/share/nginx/html/

# The rest has been redacted for brevity but is just copying of favicons etc.

Express Node Server

FROM node:10.16.2-alpine

# Create app directory
WORKDIR /app

# Install app dependencies
COPY server/package*.json .

RUN npm install

EXPOSE 8080

CMD [ "node", "server.js" ]

Kubernetes Manifest – Redacted for brevity

apiVersion: apps/v1beta1
kind: Deployment

containers:
      - name: frontend
        image: frontend-image:1.0.0
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
        volumeMounts:
        - mountPath: /etc/nginx/conf.d/default.conf
          name: config-dir
          subPath: my-config.conf

      - name: server
              image: server-image:1.0.0
              imagePullPolicy: IfNotPresent
              volumes:
              - name: config-tmpl
                configMap:
                  name: app-config
                  defaultMode: 0744
              - name: my-config-directory
                emptyDir: {}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: my-namespace
data:
  my-conf.conf: |-
    server {

        listen 80;

        server_name _;

        location api/ {
          proxy_pass  http://127.0.0.1:8080/;
        }

.....

Source: StackOverflow