Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 (i.e. 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.

like image 876
adam-beck Avatar asked Jan 07 '15 01:01

adam-beck


People also ask

How can Docker container connect to localhost?

You just need to reference it by its Docker network IP, instead of localhost or 127.0. 0.1 . Your host's Docker IP will be shown on the inet line. Connect to this IP address from within your containers to successfully access the services running on your host.

How do I connect to a nginx container?

Copy the Docker container's Nginx config file to your local file system. Add proxy_pass entries that point to your backend origin servers. Copy the config file back into the Nginx Docker container. Reload the Nginx configuration and test the setup.

Can Docker containers access local network?

As long as the server running locally on your Mac or in another docker container is listening to 0.0. 0.0 , the docker container will be able to reach out at that address.


4 Answers

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;
  }
}
like image 86
digitaldreamer Avatar answered Oct 17 '22 20:10

digitaldreamer


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.

like image 43
Abdullah Jibaly Avatar answered Oct 17 '22 22:10

Abdullah Jibaly


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;
} 
like image 5
Eli Avatar answered Oct 17 '22 21:10

Eli


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.

like image 2
Matthias Avatar answered Oct 17 '22 20:10

Matthias