我在 Docker 容器中有一个 Express api 和一个 Nginx。我希望 Nginx 反向代理对 API 的常规请求,但我希望它直接提供图像等静态文件。
但是我似乎一辈子都无法弄清楚我需要在这里使用的确切 URI,并且图像保持 404-ing。这是 docker-compose:
services:
angles-api:
build:
context: .
dockerfile: Dockerfile
container_name: api
nginx-proxy:
build:
context: .
dockerfile: Dockerfile.nginx
container_name: nginx-proxy
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- api
这是 nginx.conf
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://api:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /images/ {
alias /public/images/;
# THIS PART JUST DOESN'T WORK
}
}
我尝试了多个 URI,但我无法弄清楚其中的逻辑。 Nginx 镜像如何访问 Express 镜像中的文件?这是我得到的错误:
2024-01-07 00:00:00 nginx-proxy | 2024/01/06 00:00:00 [error] 30#30: *4 open() "/public/images/test.png" failed (2: No such file or directory), client: 172.18.0.1, server: localhost, request: "GET /images/test.png HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:2222/"
您尚未与我们分享您的 nginx Dockerfile 的内容,但看起来您从未将任何内容放入 nginx 容器中的
/public/images
目录中。
我们可以在运行时将本地
images
目录绑定到容器中,而不是将镜像构建到容器镜像中。这让我们可以使用库存 nginx 镜像,而不需要构建我们自己的镜像。
这是 Dockerfile 的稍微修改版本,似乎工作得很好:
services:
angles-api:
build:
context: api
healthcheck:
test: ["CMD", "curl", "-sSf", "http://localhost:3000"]
interval: "5s"
retries: 3
nginx-proxy:
image: docker.io/nginx:mainline
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./images:/public/images
depends_on:
angles-api:
condition: service_healthy
地点:
api/Dockerfile
包含:
FROM docker.io/alpine:latest
USER root
RUN apk add curl
RUN curl -sSfL -o /tmp/whoami.tar.gz https://github.com/traefik/whoami/releases/download/v1.10.1/whoami_v1.10.1_linux_amd64.tar.gz
RUN tar -C /usr/local/bin -xf /tmp/whoami.tar.gz whoami
ENV WHOAMI_PORT_NUMBER=3000
CMD ["/usr/local/bin/whoami"]
./nginx.conf
包含:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://angles-api:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /images/ {
alias /public/images/;
autoindex on;
}
}
并且
./images
包含:
total 160
-rw-r--r-- 1 lars lars 161352 Jan 6 21:15 uncle-deadly.png
通过上述配置,对
localhost:8080/images/
的请求将转到 nginx 容器中的 /public/images
目录:
$ curl localhost:8080/images/
<html>
<head><title>Index of /images/</title></head>
<body>
<h1>Index of /images/</h1><hr><pre><a href="../">../</a>
<a href="uncle-deadly.png">uncle-deadly.png</a> 07-Jan-2024 02:15 161352
</pre><hr></body>
</html>
对不在
/images
下的任何路径的请求都会发送到 API 容器:
$ curl localhost:8080/
Hostname: 8c7638b8d4c2
IP: 127.0.0.1
IP: 192.168.144.2
RemoteAddr: 192.168.144.3:39468
GET / HTTP/1.1
Host: localhost
User-Agent: curl/8.0.1
Accept: */*
Connection: close
X-Forwarded-For: 192.168.144.1
X-Forwarded-Proto: http
X-Real-Ip: 192.168.144.1
并且:
$ curl localhost:8080/foo/bar
Hostname: 8c7638b8d4c2
IP: 127.0.0.1
IP: 192.168.144.2
RemoteAddr: 192.168.144.3:40144
GET /foo/bar HTTP/1.1
Host: localhost
User-Agent: curl/8.0.1
Accept: */*
Connection: close
X-Forwarded-For: 192.168.144.1
X-Forwarded-Proto: http
X-Real-Ip: 192.168.144.1
此答案中引用的所有文件都可以在线找到此处。