简体   繁体   中英

How do I access a server on localhost with nginx docker container?

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 container, I am able to see the default nginx landing page. So I know that much is working.

Now I can mount my sites-enabled directory that contains the configuration for proxy_pass localhost:3000 . I have my node application running locally (not in any Docker container) and I can access it via port 3000 (ie localhost:3000 ). However, I would assume that with nginx container running, mapped to port 80, and proxying my localhost:3000, that I would be able to see my very simple (hello world) application. Instead I receive a 502.

Do I need to pass something into docker? Is this likely a nginx configuration error? Here is my nginx configuration:

server {
  listen 0.0.0.0:80;
  server_name localhost;

  location / {
    proxy_pass http://localhost:3000;
  }
}

I have tried using this question but it did not seem to help. That is unless I'm doing something completely wrong.

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 .

ie 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 .

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;
} 

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 .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM