4

I am trying to get a NGINX based reverse proxy to work in Windows/WSL2 environment. I am very new to Docker and NGINX world. I am able to get the following command to work

docker run --name nginx-test -p 8080:80 -v /home/skotekar/nginx.conf:/etc/nginx/nginx.conf:ro -v /mnt/d/site1/wwwroot:/usr/share/nginx/html:ro -d nginx:alpine

I can then browse http://localhost:8080 and view my static content just fine. As you see from the command I have a default nginx.conf in my local /home folder which gets mapped into NGINX Docker when running. It works fine the first time.

Now if I stop the container using:

docker container stop nginx-test

Then make changes to the nginx.conf file in my /home directory and want to start the container with updated configuration using following command:

docker container start nginx-test

But this command fails gives me a very confusing message:

Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:59: mounting "/run/desktop/mnt/host/wsl/docker-desktop-bind-mounts/Ubuntu-20.04/c0d0caa87ff063ee46265048f5b1ee489a8945669d39c6f6110cd578b8cda1ed" to rootfs at "/var/lib/docker/overlay2/4e6b279945acb06200b3677272774f4b5fbb6a619214decbca8c594dbbe3b8ec/merged/etc/nginx/nginx.conf" caused: no such file or directory: unknown

Only way to get it back running is to delete the container and use the first command again. Any idea how to get this working. It will be easier if I could just restart my container after making changes to config until I figure out the correct reverse proxy settings I need.

Thanks

AymDev
  • 6,626
  • 4
  • 29
  • 52
Shreedhar Kotekar
  • 1,034
  • 10
  • 20
  • I just wanted to add here that, similar change made in the html folder works fine. When I restart the container it serves up the update html files. Its only the configuration file that has problem. – Shreedhar Kotekar Jan 28 '21 at 20:32

1 Answers1

13

You do not need to restart container to reload new config. Nginx can hot-reload config without restarting.

Once you have mounted volume, you can make changes and they will be reflected in container immediately.

To test your config just execute this command:

docker exec nginx-test nginx -t

To reload new config:

docker exec nginx-test nginx -s reload

Edit! Access Windows host from Docker running in the WSL2

As per comments i am very curious about your issues, because i haven't seen them in my career.

So my steps to reproduce your use case is:

1. Download any web application for windows

I chose caddy web server as it is single binary and I know it. It is similar application to Nginx

https://caddyserver.com/download

2. Setup simple webpage on Windows Host

I prepared Caddyfile - Config for Caddy Web Server:

:80

respond "Hello, world from Caddy on Windows!"

Then i put this Caddyfile in the same directory, where I have Caddy Server binary:

PS C:\Users\Daniel\Downloads\caddy> ls


    Directory: C:\Users\Daniel\Downloads\caddy


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        29.01.2021     11:59             52 Caddyfile
-a----        29.01.2021     11:55       34081792 caddy_windows_amd64.exe

3. Start Web Server on Windows and verify it.

To start web server run: ./caddy.exe run

Example:

PS C:\Users\Daniel\Downloads\caddy> .\caddy_windows_amd64.exe run
2021/01/29 11:01:27.520 ←[34mINFO←[0m   using adjacent Caddyfile
2021/01/29 11:01:27.528 ←[34mINFO←[0m   admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}
2021/01/29 11:01:27.529 ←[34mINFO←[0m   tls.cache.maintenance   started background certificate maintenance      {"cache": "0xc000497490"}
2021/01/29 11:01:27.529 ←[34mINFO←[0m   http    server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server {"server_name": "srv0", "http_port": 80}
2021/01/29 11:01:27.530 ←[34mINFO←[0m   tls     cleaned up storage units
2021/01/29 11:01:27.532 ←[34mINFO←[0m   autosaved config        {"file": "C:\\Users\\Daniel\\AppData\\Roaming\\Caddy\\autosave.json"}
2021/01/29 11:01:27.532 ←[34mINFO←[0m   serving initial configuration

Now verify if it is working. Go to your browser and visit the http://localhost/ page:

enter image description here

4. Now verify you have WSL2 running on the windows host:

PS C:\Users\Daniel> wsl.exe --list --all -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         2

If yes shell there with command wsl

5. Start docker daemon

daniel@DESKTOP-K8UQA2E:~$ sudo service docker start
 * Starting Docker: docker

6. Check your IPv4 address for WSL Network adapter in the Windows and Linux

Open powershell and execute the ifconfig command, then find WSL network adapter:

Ethernet adapter vEthernet (WSL):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::e96c:c3d6:464e:2a3b%72
   IPv4 Address. . . . . . . . . . . : 172.20.240.1
   Subnet Mask . . . . . . . . . . . : 255.255.240.0
   Default Gateway . . . . . . . . . :

Your Windows IP is 172.20.240.1

Then go to WSL and execute curl 172.20.240.1, to check if your hosts are connected.

daniel@DESKTOP-K8UQA2E:~$ curl 172.20.240.1
Hello, world from Caddy on Windows!d

Now figure out the Linux Host IP with the ip a command and see IP in the same network as Windows:

5: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:ce:28:8e brd ff:ff:ff:ff:ff:ff
    inet 172.20.252.177/20 brd 172.20.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:fece:288e/64 scope link
       valid_lft forever preferred_lft forever

7. Prepare simple nginx configuration

worker_processes  5;  ## Default: 1
worker_rlimit_nofile 8192;

events {
  worker_connections  4096;  ## Default: 1024
}

http {
  index    index.html index.htm index.php;

  default_type application/octet-stream;
  sendfile     on;
  tcp_nopush   on;
  server_names_hash_bucket_size 128; # this seems to be required for some vhosts


  server { # simple load balancing
    listen          80;

     location / {
      return  200 "Hello World from Nginx in Linux";
    }

    location /windows {
      proxy_pass      http://172.20.240.1/;
    }
  }
}

This is very simple config

8. Start the docker with host networking mode.

If you do not want to use the host networking, you have to do forwarding packets from docker network to the wsl network because your docker will not have access to windows host directly.

But let's say you can start container with host networking.

Run this command:

daniel@DESKTOP-K8UQA2E:~/nginx-test$ sudo docker run -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf --name="nginx-local" --network=host  -d nginx:latest

Verify your docker is working fine:

daniel@DESKTOP-K8UQA2E:~/nginx-test$ sudo docker logs nginx-local
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
daniel@DESKTOP-K8UQA2E:~/nginx-test$ sudo docker ps | grep nginx

de9873314b77        nginx:latest           "/docker-entrypoint.…"   20 seconds ago      Up 19 seconds

8. Try to get response from linux and windows

daniel@DESKTOP-K8UQA2E:~/nginx-test$ curl localhost
Hello World from Nginx in Linux
daniel@DESKTOP-K8UQA2E:~/nginx-test$ curl localhost/windows
Hello, world from Caddy on Windows!
daniel@DESKTOP-K8UQA2E:~/nginx-test$
AymDev
  • 6,626
  • 4
  • 29
  • 52
Daniel Hornik
  • 1,957
  • 1
  • 14
  • 33
  • trying that now – Shreedhar Kotekar Jan 28 '21 at 21:07
  • Not sure it is working as you said. I changed the conf file on my host. Then cli into container and did a cat /etc/ngnix/nginx.conf and it still shown the old config and not my updated config – Shreedhar Kotekar Jan 28 '21 at 21:14
  • Ahh yes, because you have read only in the volume. Provably for development purposes you can remove `:ro` from your volume mount – Daniel Hornik Jan 28 '21 at 21:16
  • hmm, thats what that means! Let me try it – Shreedhar Kotekar Jan 28 '21 at 23:37
  • That seem to work. I still cannot get the ngnix container to see the changes made from host side, but at least I can cli into the container and change the config there directly. This should speed up the process of testing changes in config. Thank you very much @Daniel Hornik – Shreedhar Kotekar Jan 28 '21 at 23:44
  • another follow-up question. I got the reverse proxy to work this way ```Windows -> WSL2 -> Docker -> Nginx Container``` Any request that nginx receive has to forward it to another web app running on the Windows itself on a different port. How to specify in the nginx.conf to reach out to windows box? Using localhost does not work, I think it points back to nginx itself. Using the hostname of windows pc did not work either as the container doesn't know how to resolve it. What host name should I use get out of container and reach the host machine? – Shreedhar Kotekar Jan 29 '21 at 04:18
  • 1
    Hi @ShreedharKotekar I have prepared simple instruction for you :) How to do what you want – Daniel Hornik Jan 29 '21 at 11:30
  • Ohh man, you put so much time into this. Greatly appreciated. After looking at your instructions which are excellent, I found out what I was doing wrong. I think in Step 6, you used the IP address of WSL NIC and used that in Step 7 on your proxy_pass line for /windows. I was trying to use localhost, 127.0.0.1 and hostname of the windows computer there and it did not work. After doing what you suggested, the proxy_pass is correctly forwarding the request to web server running on windows. Thanks again so much. – Shreedhar Kotekar Jan 29 '21 at 18:48