如何让 NGINX 在 Docker 中运行以重新加载 nginx.conf 配置

Shr*_*kar 6 nginx docker windows-subsystem-for-linux nginx-config wsl-2

我正在尝试让基于 NGINX 的反向代理在 Windows/WSL2 环境中工作。我对 Docker 和 NGINX 世界非常陌生。我能够让以下命令工作

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
Run Code Online (Sandbox Code Playgroud)

然后我可以浏览 http://localhost:8080 并查看我的静态内容。正如您从命令中看到的,我的本地/home文件夹中有一个默认的nginx.conf,运行时该文件夹会映射到 NGINX Docker。第一次效果很好。

现在,如果我使用以下命令停止容器:

docker container stop nginx-test
Run Code Online (Sandbox Code Playgroud)

然后对/home目录中的nginx.conf文件进行更改,并希望使用以下命令启动具有更新配置的容器:

docker container start nginx-test
Run Code Online (Sandbox Code Playgroud)

但是这个命令失败给了我一个非常令人困惑的消息:

来自守护进程的错误响应:OCI 运行时创建失败:container_linux.go:370: 启动容器进程导致:process_linux.go:459: 容器初始化导致:rootfs_linux.go:59: 挂载“/run/desktop/mnt/host/wsl/ docker-desktop-bind-mounts/Ubuntu-20.04/c0d0caa87ff063ee46265048f5b1ee489a8945669d39c6f6110cd578b8cda1ed”到 rootfs 位于“/var/lib/docker/overlay2/4e6b279945acb06200b3677272774f 4b5fbb6a619214decbca8c594dbbe3b8ec/merged/etc/nginx/nginx.conf”导致:没有这样的文件或目录:未知

让它重新运行的唯一方法是删除容器并再次使用第一个命令。知道如何让它发挥作用。如果我可以在更改配置后重新启动容器,直到找出所需的正确反向代理设置,那就更容易了。

谢谢

Dan*_*nik 18

您不需要重新启动容器来重新加载新配置。Nginx 可以热重载配置而无需重新启动。

\n

一旦安装了卷,您就可以进行更改,它们将立即反映在容器中。

\n

要测试您的配置,只需执行以下命令:

\n
docker exec nginx-test nginx -t\n
Run Code Online (Sandbox Code Playgroud)\n

要重新加载新配置:

\n
docker exec nginx-test nginx -s reload\n
Run Code Online (Sandbox Code Playgroud)\n

编辑!从 WSL2 中运行的 Docker 访问 Windows 主机

\n

根据评论,我对你的问题很好奇,因为我在我的职业生涯中没有见过它们。

\n

所以我重现您的用例的步骤是:

\n

1. 下载任何适用于 Windows 的 Web 应用程序

\n

我选择了 caddy Web 服务器,因为它是单个二进制文件,而且我知道这一点。与 Nginx 类似的应用

\n

https://caddyserver.com/download

\n

2. 在Windows主机上设置简单的网页

\n

我准备了Caddyfile- Caddy Web 服务器的配置:

\n
:80\n\nrespond "Hello, world from Caddy on Windows!"\n
Run Code Online (Sandbox Code Playgroud)\n

然后我将其放在Caddyfile同一目录中,其中有 Caddy Server 二进制文件:

\n
PS C:\\Users\\Daniel\\Downloads\\caddy> ls\n\n\n    Directory: C:\\Users\\Daniel\\Downloads\\caddy\n\n\nMode                 LastWriteTime         Length Name\n----                 -------------         ------ ----\n-a----        29.01.2021     11:59             52 Caddyfile\n-a----        29.01.2021     11:55       34081792 caddy_windows_amd64.exe\n
Run Code Online (Sandbox Code Playgroud)\n

3. 在Windows 上启动Web Server 并验证它。

\n

要启动网络服务器,请运行:./caddy.exe run

\n

例子:

\n
PS C:\\Users\\Daniel\\Downloads\\caddy> .\\caddy_windows_amd64.exe run\n2021/01/29 11:01:27.520 \xe2\x86\x90[34mINFO\xe2\x86\x90[0m   using adjacent Caddyfile\n2021/01/29 11:01:27.528 \xe2\x86\x90[34mINFO\xe2\x86\x90[0m   admin   admin endpoint started  {"address": "tcp/localhost:2019", "enforce_origin": false, "origins": ["localhost:2019", "[::1]:2019", "127.0.0.1:2019"]}\n2021/01/29 11:01:27.529 \xe2\x86\x90[34mINFO\xe2\x86\x90[0m   tls.cache.maintenance   started background certificate maintenance      {"cache": "0xc000497490"}\n2021/01/29 11:01:27.529 \xe2\x86\x90[34mINFO\xe2\x86\x90[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}\n2021/01/29 11:01:27.530 \xe2\x86\x90[34mINFO\xe2\x86\x90[0m   tls     cleaned up storage units\n2021/01/29 11:01:27.532 \xe2\x86\x90[34mINFO\xe2\x86\x90[0m   autosaved config        {"file": "C:\\\\Users\\\\Daniel\\\\AppData\\\\Roaming\\\\Caddy\\\\autosave.json"}\n2021/01/29 11:01:27.532 \xe2\x86\x90[34mINFO\xe2\x86\x90[0m   serving initial configuration\n
Run Code Online (Sandbox Code Playgroud)\n

现在验证它是否正常工作。转到您的浏览器并访问该http://localhost/页面:

\n

在此输入图像描述

\n

4. 现在验证您是否已在 Windows 主机上运行 WSL2:

\n
PS C:\\Users\\Daniel> wsl.exe --list --all -v\n  NAME            STATE           VERSION\n* Ubuntu-20.04    Running         2\n
Run Code Online (Sandbox Code Playgroud)\n

如果是的话,使用命令 shellwsl

\n

5.启动docker守护进程

\n
daniel@DESKTOP-K8UQA2E:~$ sudo service docker start\n * Starting Docker: docker\n
Run Code Online (Sandbox Code Playgroud)\n

6. 检查 Windows 和 Linux 中 WSL 网络适配器的 IPv4 地址

\n

打开powershell并执行ifconfig命令,然后找到WSL网络适配器:

\n
Ethernet adapter vEthernet (WSL):\n\n   Connection-specific DNS Suffix  . :\n   Link-local IPv6 Address . . . . . : fe80::e96c:c3d6:464e:2a3b%72\n   IPv4 Address. . . . . . . . . . . : 172.20.240.1\n   Subnet Mask . . . . . . . . . . . : 255.255.240.0\n   Default Gateway . . . . . . . . . :\n
Run Code Online (Sandbox Code Playgroud)\n

您的 Windows IP 是172.20.240.1

\n

然后进入 WSL 并执行curl 172.20.240.1,检查您的主机是否已连接。

\n
daniel@DESKTOP-K8UQA2E:~$ curl 172.20.240.1\nHello, world from Caddy on Windows!d\n
Run Code Online (Sandbox Code Playgroud)\n

现在使用以下命令找出 Linux 主机 IP ip a,并查看与 Windows 位于同一网络中的 IP:

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

7.准备简单的nginx配置

\n
worker_processes  5;  ## Default: 1\nworker_rlimit_nofile 8192;\n\nevents {\n  worker_connections  4096;  ## Default: 1024\n}\n\nhttp {\n  index    index.html index.htm index.php;\n\n  default_type application/octet-stream;\n  sendfile     on;\n  tcp_nopush   on;\n  server_names_hash_bucket_size 128; # this seems to be required for some vhosts\n\n\n  server { # simple load balancing\n    listen          80;\n\n     location / {\n      return  200 "Hello World from Nginx in Linux";\n    }\n\n    location /windows {\n      proxy_pass      http://172.20.240.1/;\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是非常简单的配置

\n

8. 以网络模式启动docker host

\n

如果您不想使用host网络,则必须将数据包从 docker 网络转发到 wsl 网络,因为您的 docker 将无法直接访问 Windows 主机。

\n

但假设您可以通过host网络启动容器。

\n

运行这个命令:

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

验证您的 docker 工作正常:

\n
daniel@DESKTOP-K8UQA2E:~/nginx-test$ sudo docker logs nginx-local\n/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration\n/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/\n/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh\n10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf\n10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf\n/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh\n/docker-entrypoint.sh: Configuration complete; ready for start up\ndaniel@DESKTOP-K8UQA2E:~/nginx-test$ sudo docker ps | grep nginx\n\nde9873314b77        nginx:latest           "/docker-entrypoint.\xe2\x80\xa6"   20 seconds ago      Up 19 seconds\n
Run Code Online (Sandbox Code Playgroud)\n

8. 尝试获取linux和windows的响应

\n
daniel@DESKTOP-K8UQA2E:~/nginx-test$ curl localhost\nHello World from Nginx in Linux\ndaniel@DESKTOP-K8UQA2E:~/nginx-test$ curl localhost/windows\nHello, world from Caddy on Windows!\ndaniel@DESKTOP-K8UQA2E:~/nginx-test$\n
Run Code Online (Sandbox Code Playgroud)\n