Nginx proxy instead of webpack (via docker)
A proxy is needed to solve CORS problems when contacting the backend
Frontend and backend normally run on different domains causing CORS problems, so you normally need to have the backend responding under a subpath (/api) under the same domain where the FE is served.
Webpack or Nginx ?
You can solve that via webpack proxy, but you can also us the more advanced nginx that will be likely also be used in production, so you have to write the config just once, and you can implement advanced mechanism (like the auth_request).
Nginx proxy running via docker and wrapping react-scripts
I’m going to show how to run a dockerised nginx proxy that “wraps” your current application in dev mode (react-scripts start / npm run start) on the fly, without the need to rebuild anything when a change is made.
- Create a docker-compose.yml file where you specify the exact nginx version used on prod
version: '3.1'services:
ui_proxy:
container_name: myapp_ui_proxy
restart: on-failure
image: "nginx:1.18.0-alpine"
volumes:
- ./nginx-local-proxy.conf:/etc/nginx/conf.d/default.conf:ro
ports:
- 8080:8080
2. Create a Makefile with a start
target to make it easier to launch the whole thing with make start
.PHONY: help start
start:
npm run start:proxied
# perform checks if needed
docker-compose up -d ui_proxy
proxy-stop:
docker-compose stop ui_proxy
proxy-reload-config:
docker exec -it bolt_ui_proxy nginx -s reload || echo ui_proxy not running
proxy-logs-tail:
docker logs -f bolt_ui_proxy
3. Add the package.json custom start:proxed
script that launches webpack on the port 3000. In case you are not using webpack, just launch npm run start
from the previous step (and make sure it’s reachable from the proxy like I did for webpack arguments below)
{
"scripts": {
...
"start": "webpack-dev-server --config .webpack.dev.js",
"start:proxied": "webpack-dev-server --config .webpack.dev.js --host=0.0.0.0 --port=3000 --disableHostCheck=true",
...
}
}
4. and last, the nginx-local-proxy.conf . Replace 5000
with the port the API listens to. You might need a rewrite rule if you need to strip the “api” part. The /
means that everything not prefixed by /api
goes straight to webpack.
Important: you cannot use `localhost` here as we are inside a docker container network. To listen to the host port (your machine where webpack and the API listens to) you have to use host.docker.internal. If your services run via the docker-compose file, then you can access them via their name (e.g. http://api:5000 if you have an api
entry in the docker-compose).
server {
listen 8080 default_server;
listen [::]:8080 default_server;
location /api {
proxy_pass http://host.docker.internal:5000;
}
location / {
proxy_pass http://host.docker.internal:3000;
}
}
Usage
just type make start
to launch webpack, and the proxy.
If you are making a change to the nginx proxy config, type make proxy-stop
. To watch the proxy logs, make proxy-logs-tail