6

The Error

When deploying to Azure Web Apps with Multi-container support, I receive an "Invalid Host Header" message from https://mysite.azurewebsites.com

Local Setup

This runs fine.

I have two Docker containers: client a React app and server an Express app hosting my API. I am using a proxy to host my API on server.

In client's package.json I have defined:

"proxy": "http://localhost:3001"

I use the following docker compose file to build locally.

version: '2.1'

services:
  server:
    build: ./server
    expose:
      - ${APP_SERVER_PORT}
    environment:
      API_HOST: ${API_HOST}
      APP_SERVER_PORT: ${APP_SERVER_PORT}
    ports: 
      - ${APP_SERVER_PORT}:${APP_SERVER_PORT}
    volumes: 
      - ./server/src:/app/project-server/src
    command: npm start

  client: 
    build: ./client
    environment: 
      - REACT_APP_PORT=${REACT_APP_PORT}
    expose:
      - ${REACT_APP_PORT}
    ports:
      - ${REACT_APP_PORT}:${REACT_APP_PORT}
    volumes:
      - ./client/src:/app/project-client/src
      - ./client/public:/app/project-client/public
    links:
      - server
    command: npm start

Everything runs fine.

On Azure

When deploying to Azure I have the following. client and server images have been stored in Azure Container Registry. They appear to load just fine from the logs.

In my App Service > Container Settings I am loading the images from Azure Container Registry (ACR) and I'm using the following configuration (Docker compose) file.

version: '2.1'

services:
  client: 
    image: <clientimage>.azurecr.io/clientimage:v1
    build: ./client
    expose:
      - 3000
    ports:
      - 3000:3000
    command: npm start

  server:
    image: <serverimage>.azurecr.io/<serverimage>:v1
    build: ./server
    expose:
      - 3001
    ports: 
      - 3001:3001
    command: npm start

I have also defined in Application Settings:

WEBSITES_PORT to be 3000.

This results in the error on my site "Invalid Host Header"

Things I've tried

• Serving the app from the static folder in server. This works in that it serves the app, but it messes up my authentication. I need to be able to serve the static portion from client's App.js and have that talk to my Express API for database calls and authentication.

• In my docker-compose file binding the front end to:

ports:
 - 3000:80

• A few other port combinations but no luck.

Also, I think this has something to do with the proxy in client's package.json based on this repo

Any help would be greatly appreciated!

Update

It is the proxy setting.

This somewhat solves it. By removing "proxy": "http://localhost:3001" I am able to load the website, but the suggested answer in the problem does not work for me. i.e. I am now unable to access my API.

Ian Leatherbury
  • 364
  • 4
  • 11

2 Answers2

0

Never used azure before and I also don't use a proxy (due to its random connection issues), but if your application is basically running express, you can utilize cors. (As a side note, it's more common to run your express server on 5000 than 3001.)

I first set up an env/config.js folder and file like so:

module.exports = {
  development: {
    database: 'mongodb://localhost/boilerplate-dev-db',
    port: 5000,
    portal: 'http://localhost:3000',
  },
  production: {
    database: 'mongodb://localhost/boilerplate-prod-db',
    port: 5000,
    portal: 'http://example.com',
  },
  staging: {
    database: 'mongodb://localhost/boilerplate-staging-db',
    port: 5000,
    portal: 'http://localhost:3000',
  }
};

Then, depending on the environment, I can implement cors where I'm defining express middleware:

const cors = require('cors');
const config = require('./path/to/env/config.js');
const env = process.env.NODE_ENV;

app.use(
    cors({
      credentials: true,
      origin: config[env].portal,
    }),
  );

Please note the portal and the AJAX requests MUST have matching host names. For example, if my application is hosted on http://example.com, my front-end API requests must be making requests to http://example.com/api/ (not http://localhost:3000/api/ -- click here to see how I implement it for my website), and the portal env must match the host name http://example.com. This set up is flexible and necessary when running multiple environments.

Or if you're using the create-react-app, then simply eject your app and implement a proxy inside the webpack production configuration.

Or migrate your application to my fullstack boilerplate, which implements the cors example above.

Matt Carlotta
  • 18,972
  • 4
  • 39
  • 51
  • Thank you for your reply! I'm still exploring options here, so I will post when I have a working solution. – Ian Leatherbury Oct 27 '18 at 17:29
  • Perhaps this is another solution: https://stackoverflow.com/questions/43619644/i-am-getting-an-invalid-host-header-message-when-running-my-react-app-in-a-we – Matt Carlotta Oct 27 '18 at 19:18
0

So, I ended up having to move off of containers and serve the React app up in more of a typical MERN architecture with the Express server hosting the React app from the static build folder. I set up some routes with PassportJS to handle my authentication.

Not my preferred solution, I would have preferred to use containers, but this works. Hope this points someone out there in the right direction!

Ian Leatherbury
  • 364
  • 4
  • 11