1

An angular app running in the browser makes backend API requests. The URL of these requests is determined by concatenating the protocol + domain + port specified in the corresponding environment-*.ts file and a path.

The protocol + domain + port part can be 'overridden' using a proxy. However, this can be done only when we ng serve the app. Once we ng build, these are hardwired into the ./dist artifacts.

Now consider a staging configuration. Ideally, the protocol + domain + port would be http://localhost:4200. This way anybody can run the entire web app locally. If the frontend, backend, and database services are all specified in a docker-compose.yml file, one can start and stop the whole thing (swarm?) using a single command. No need to play with system files, such as /etc/hosts.

Enter e2e tests. These tests need their own JVM, headless browser, and other dependencies. So they too come in a docker image. However, from their perspective, localhost is different from our localhost. All they see is the loopback address of their container. There are two ways to allow these e2e tests to access the app on the correct localhost:

  1. Start the e2e tests container with --network host option.
  2. Start the e2e tests container with --add-host host.docker.internal:host-gateway — this makes the good localhost accessible under host.docker.internal.

Unfortunately 1. does not work on docker for Mac, so developers using MacBooks could not run e2e tests. We are limited to 2., which means each backend API request needs to go to host.docker.internal instead of localhost, which means another environment-*.ts and another frontend build.

Is there a way to access a single build of an angular app on both localhost and from within a locally running docker container?

I tried to edit /etc/hosts on my computer to see if I can map localhost to any IP address I want. This way, I would map localhost in the /etc/hosts of the e2e tests' docker image to the IP address of host.docker.internal. However, this seems not to work. I can map a bogus domain to the IP address of google and it works, but if I map localhost, nothing happens.

Martin Drozdik
  • 12,742
  • 22
  • 81
  • 146
  • 1
    Have you tried using something like `/api` (no protocol, host, port -- just absolute path)? That's how I configure my Angular apps in multi-domain environment, everything works fine so far. – alx Sep 06 '22 at 19:23

0 Answers0