Nginx reverse proxy not finding other internal Docker container using hostname - docker

I have two docker containers. One runs Kestrel (172.17.0.3), The other runs Nginx (172.17.0.4) using a reverse proxy to connect to Kestrel. Nginx connects fine when I use internal Docker ip of Kestrel container but when I try to connect to Kestrel using container's hostname in nginx.conf (kestral) I get following error:
2020/06/30 00:23:03 [emerg] 58#58: host not found in upstream "kestrel" in /etc/nginx/nginx.conf:7
nginx: [emerg] host not found in upstream "kestrel" in /etc/nginx/nginx.conf:7
I launched containers with these two lines
docker run -d --name kestrel --restart always -h kestrel mykestrelimage
docker run -d --name nginx --restart always -p 80:80 -h nginx mynginximage
My nginx.conf file below.
http {
# I've tried with and without line below that I found on Stackoverflow
resolver 127.0.0.11 ipv6=off;
server {
listen 80;
location / {
# lines below don't work
# proxy_pass http//kestrel:80;
# proxy_pass http//kestrel
# proxy_pass http//kestrel:80/;
# proxy_pass http//kestrel/;
# when I put internal docker ip of Kestrel server works fine
proxy_pass http://172.17.0.3:80/;
}
}
}
events {
}

I figured out solution to my problem. There were two issues.
First problem: By default Docker uses default bridge network when creating containers. The default Docker bridge network does not resolve DNS though. You have to create a custom bridge network and then specify network when creating docker containers. The below allowed me to ping between containers using hostname
docker network create --driver=bridge mycustomnetwork
docker run -d --name=kestrel --restart=always -h kestrel.local --network=mycustomnetwork mykestrelimage
docker run -d --name=nginx --restart always -p 80:80 -h nginx.local --network=mycustomnetwork mynginximage
Second problem: Even though it was only one kestrel server for some reason Nginx required that I setup an upstream section in /etc/nginx/nginx.conf
http {
upstream backendservers {
server kestrel;
}
server {
listen 80;
location / {
proxy_pass http://backendservers/;
}
}
}
events {
}

Related

Docker nginx dynamic proxy_pass is not working

I want to access docker container by name in nginx reverse proxy which is also a docker container.
nginx configuration is as follow
server {
server_name domain.com;
location / {
proxy_pass http://host.docker.internal:3000;
}
}
server {
server_name api-sub.domain.com;
resolver 127.0.0.11 valid=10s ipv6=off;
location / {
proxy_pass http://$arg_subdomain:3001;
}
}
server {
server_name ~^(?<subdomain>\w+).domain\.com$;
resolver 127.0.0.11 valid=10s ipv6=off;
location / {
proxy_pass http://$subdomain:3002;
}
}
The first application is running on host os and working fine. Apart from first all container running in same user defined docker network but they are ginving 502 Bad Gateway. So I think that the resolver not providing IP against docker container. I am running the container using the following command
-- nginx
docker run -p 80:80 -d --network="user-defined-network" --restart always --add-host=host.docker.internal:host-gateway image-nginx
-- other container
docker run -d --network user-defined-network image-solution
Can someone please help me.

Connection refused: when uwsgi and nginx in different containers

I am trying to setup two docker containers(yes separate without docker-compose): one with nginx and one with uwsgi with basic flask app.
I run containers in same network within docker
My nginx config for site added/linked to sites-enabled(everything else is default):
server {
listen 80;
server_name 127.0.0.1;
location / {
include uwsgi_params;
uwsgi_pass 0.0.0.0:8080;
}
}
My uwsgi.ini
[uwsgi]
module = app:app
master = true
processes = 2
socket = 0.0.0.0:8080
uwsgi entry point in docker looks like
.local/bin/uwsgi --ini uwsgi.ini
Containers run fine on their own - uwsgi receives request on 8080 and nginx receives expected requests. How ever when I try to access 127.0.0.1 i get 502 status code and nginx logs error:
1 connect() failed (111: Connection refused) while connecting to
upstream, client: 192.168.4.1, server: 127.0.0.1, request: "GET /
HTTP/1.1", upstream: "uwsgi://0.0.0.0:8080", host: "127.0.0.1"
By googling i find solution that rather use one container and some_socket.sock as file or use docker compose. Apparently problem with permissions, but I do not know how to solve them or diagnose.
I launch containers with these commands:
docker run --network app_network --name nginx --rm -p 80:80 my_nginx
docker run --network app_network --name flaskapp --rm -p 8080:8080 my_uwsgi
EDIT
You can simply use the hostname of the docker container in the uwsgi_pass directive as both docker containers are on the same subnet.
location / {
include uwsgi_params;
uwsgi_pass flaskapp:8080;
}
0.0.0.0 isn't the IP address of the server, it essentially tells the server to be hosted on every IP that the device has allocated.
To connect to it from nginx, you will need to use the IP address of the container instead.
You can find the IP address of the container running uWsgi with the following command:
docker inspect CONTAINER_ID
Where CONTAINER_ID is the ID of the container you started uwsgi in.
From here you can update the nginx config as follows:
uwsgi_pass IP_ADDRESS:8080;
Where IP_ADDRESS is the one you found from the command above
You can also set the ip address of the container when you start it with the following option
--ip <ip>
Be careful, however, to ensure that the IP address you set is in the same subnet as the standard IP's assigned.

how to reach another two containers with cpprest from a dockerised nginx

i have 2 docker containers with cpprest runned in:
docker run -it -p 0.0.0.0:8081:8080
and
docker run -it -p 0.0.0.0:8082:8080
I have nginx in docker container runned in: docker run -it -p 0.0.0.0:8083:8080
my nginx.conf file is:
http {
upstream backend {
server 0.0.0.0:8081;
server 0.0.0.0:8082;
}
# This server accepts all traffic to port 80 and passes it to the upstream.
# Notice that the upstream name and the proxy_pass need to match.
server {
listen 80;
location / {
proxy_pass http://backend/;
}
}
}
When nginx isn't in a container all works fine, but when i try with dockerised nginx and open 0.0.0.0:8083 - it gives me :

PhpStorm debugger with a docker container, nginx in reverse proxy and https

I need some help in order to configure PhpStorm debugger with a particular development configuration.
On my pc (192.168.1.23) I have the source code of a PHP project, a dbms and an instance of nginx as reverse proxy. Nginx is configured in order to send all the traffic to a docker container:
server {
listen 80;
listen [::]:80;
server_name www.mysite.local;
root /usr/share/nginx/html/;
# pass PHP scripts to FastCGI server
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location / {
index index.html index.php;
}
}
upstream backend {
# configuration in order to use apache inside docker container
server 172.17.0.2:80;
}
The docker container (172.17.0.2) has been created with:
docker run -dP --add-host=db.local:172.17.0.1 \
-e remote_connect_back_xdbg=1 \
-e remote_host_xdbg='192.168.1.23' \
-v /opt/live:/opt/live \
--name local_php_apache_container local_php_apache_image
So Docker mounts my project (located at /opt/live) inside /opt/live of the container. The container is a Debian 9 with PHP 5.3 + Apache2.
And it is started automatically at the boot of the pc with this command:
docker exec -it local_php_apache_container /bin/bash
Inside the docker container, the xdebug configuration in php.ini is:
[xdebug]
xdebug.remote_connect_back=${remote_connect_back_xdbg}
xdebug.remote_enable=1
xdebug.remote_port=10123
xdebug.remote_handler=dbgp
xdebug.remote_log=/stackdriver/log/xdebug.log
xdebug.remote_mode=req
xdebug.remote_autostart=1
xdebug.remote_host=${remote_host_xdbg}
xdebug.idekey="netbeans-xdebug"
The idkey is netbeans-xdebug because with netbeans, the debugger works properly (https://www.mysite.local/index.php?XDEBUG_SESSION_START=netbeans-xdebug, https with a local untrusted certificate)
But I have a lot of problems with PHPStorm and the position of PHP interpreter, both with PHP Build-in Web Server and with PHP Remote Debug configuration...
Any suggestions?

Nginx reverse proxy to an app in host

I have an app that is running outside Docker on port 5000. I am trying to run a reverse proxy in nginx via Docker compose but am unable to communicate with the host's port 5000. In my docker-compose.yml file I have:
ports:
- 80:80
- 443:443
- 5000:5000
When I try to run this I get:
ERROR: for nginx Cannot start service nginx: driver failed programming external connectivity on endpoint nginx (374026a0d34c8b6b789dcd82d6aee6c4684b3201258cfbd3fb18623c4101): Error starting userland proxy: listen tcp 0.0.0.0:5000: bind: address already in use
If I comment out - 5000:5000 I get:
[error] 6#6: *1 connect() failed (111: Connection refused) while connecting to upstream
How do I connect to an already running app in the Host from a Docker nginx container?
EDIT:
My nginx.conf file
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
upstream mysite {
server 0.0.0.0:5000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://mysite;
}
}
}
The response when I try to curl localhost is 502 Bad Gateway. The app itself and curl 127.0.0.1:5000 responds fine from the host.
EDIT 2:
I have also tried the solution found here but I get nginx: [emerg] host not found in upstream "docker". Docker is my host's hostname.
EDIT 3:
My docker-compose.yml
version: '3'
services:
simple:
build: ./simple
container_name: simple
ports:
- 80:80
- 443:443
My Dockerfile:
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
EDIT:
I am getting the computer host via the "hostname" command in linux.
The problem lies with 0.0.0.0:5000. Since Nginx is running inside the docker, it tries to find this address inside docker machine but fails since there is nothing running on 0.0.0.0:5000 inside docker.
So in order to resolve this
You need to give it an address that it can reach. Solving it requires that you
first run your application at 0.0.0.0:5000 on your host machine i.e you should be able to open your application at 0.0.0.0:5000 from your browser.
Find your IP address. once you get your IP address you should be able to
open you application through ip_address:5000. since your docker and host share the same network this address can be reached from docker also
Now, replace the 0.0.0.0:5000 in your Nginx conf file with this ip_address:5000. you would be able to serve your application
172.17.0.1 is the default host ip available to docker container running on host.
Just use 172.17.0.1:5000 in your nginx conf file and you should be able to connect to your application running on host outside the container.
My docker version is 19.03.12 where I tested the same.
I need to use a different variable to access the host container: http://host.docker.internal.
Note: I'm running on a Windows host. Not sure if that matters.

Resources