I\'m trying to use a dockerized version of nginx as a proxy server for my node (ExpressJS) application. Without any configuration to nginx and publishing port 80 for the con
Yes. Docker needs to know about your host machine. You can set an alias to that with the --add-host
switch. On a *nix box to create an alias to a name "localbox", this would be:
docker run my_repo/my_image --add-host=localbox:<host_name>`
On boot2docker it would be:
docker run my_repo/my_image --add-host=localbox:192.168.59.3`
where you should replace "192.168.59.3" with whatever boot2docker ip
returns.
Then, you should access your host machine always through the alias localbox, so just change your nginx config to:
location / {
proxy_pass http://localbox:3000;
}
And finally, if you are using Nginx as a reverse proxy for multiple services, you can spin all of that with docker-compose. Make sure to expose ports “80:80” only on the Nginx service. Other services you can expose only the service port without mapping to the underlying network like so:
web:
.....
expose:
- 8080
nginx:
.....
port:
- “80:80”
and then use Nginx configuration proxy_pass http://service-name:port You don’t need the upstream app part at all
If you're using docker-for-mac 18.03 or newer it auto creates a special DNS entry host.docker.internal
that dynamically binds to the host inet ip. You can then use the dns name to proxy services running on the host machine from inside a container as a stand-in for localhost
.
i.e. an nginx config file:
server {
listen 0.0.0.0:80;
server_name localhost;
location / {
proxy_pass http://host.docker.internal:3000;
}
}
You can get your current IP address as shown here:
ifconfig en0 | grep inet | grep -v inet6 | awk '{print $2}'
Then you can use the --add-host
flag with docker run
:
docker run --add-host localnode:$(ifconfig en0 | grep inet | grep -v inet6 | awk '{print \$2}') ...
In your proxypass
use localnode
instead of localhost
.
On linux, this works for me:
In the docker-compose.yml, mount an entrypoint script into the nginx container:
nginx:
image: nginx:1.19.2
# ...
volumes:
- ./nginx-entrypoint.sh:/docker-entrypoint.d/nginx-entrypoint.sh:ro
The contents of the entrypoint map a local address to the host local address.
apt update
apt install iproute2 -y
echo "`ip route | awk '/default/ { print $3 }'`\tdocker.host.internal" >> /etc/hosts
Then, instead of using localhost
inside the container, you can use docker.host.internal
.