docker 内的 Rust actix_web 无法实现,为什么?

Rust actix_web inside docker isn't attainable, why?

我正在尝试为我的 Rust 程序制作一个 docker 容器,让我们看看

Docker 文件

FROM debian

RUN apt-get update && \
    apt-get -y upgrade && \
    apt-get -y install git curl g++ build-essential

RUN curl https://sh.rustup.rs -sSf | bash -s -- -y

WORKDIR /usr/src/app

RUN git clone https://github.com/unegare/rust-actix-rest.git

RUN ["/bin/bash", "-c", "source $HOME/.cargo/env; cd ./rust-actix-rest/; cargo build --release; mkdir uploaded"]

EXPOSE 8080

ENTRYPOINT ["/bin/bash", "-c", "echo 'Hello there!'; source $HOME/.cargo/env; cd ./rust-actix-rest/; cargo run --release"]

cmd 到 运行:docker run -it -p 8080:8080 rust_rest_api/dev

但是从外部 curl -i -X POST -F files[]=@img.png 127.0.0.1:8080/upload 卷曲会导致 curl: (56) Recv failure: Соединение разорвано другой стороной 即被通道的另一端拒绝

但在容器内:

root@43598d5d9e85:/usr/src/app# lsof -i
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
actix_003   6 root    3u  IPv4 319026      0t0  TCP localhost:http-alt (LISTEN)

但是 运行在没有 docker 的情况下使程序正常工作并充分处理来自 curl 的相同请求。

容器内部:

root@43598d5d9e85:/usr/src/app# curl -i -X POST -F files[]=@i.jpg 127.0.0.1:8080/upload
HTTP/1.1 100 Continue

HTTP/1.1 201 Created
content-length: 70
content-type: application/json
date: Wed, 24 Jul 2019 08:00:54 GMT

{"keys":["uploaded/5nU1nHznvKRGbkQaWAGJKpLSG4nSAYfzCdgMxcx4U2mF.jpg"]}

外面的问题是什么?

如果您像我一样按照 Actix 网站上的示例进行操作,您可能会编写类似这样的内容,或者类似的内容:

fn main() {
    HttpServer::new(|| {
        App::new()
            .route("/", web::get().to(index))
            .route("/again", web::get().to(index2))
    })
    .bind("127.0.0.1:8088")
    .unwrap()
    .run()
    .unwrap();
}

这里的问题是您要绑定到特定 IP,而不是使用 0.0.0.0 绑定到主机容器上的所有 IP。我遇到了和你一样的问题,通过将我的代码更改为:

解决了这个问题
fn main() {
    HttpServer::new(|| {
        App::new()
            .route("/", web::get().to(index))
            .route("/again", web::get().to(index2))
    })
    .bind("0.0.0.0:8088")
    .unwrap()
    .run()
    .unwrap();
}

这对你来说可能不是问题,如果没有看到 运行 服务器的代码,我无法知道。

为了完成 John 所说的,在我的例子中我不得不使用一个元组:.bind( ("0.0.0.0", 8088) )

为了让我的 Docker/Actix 后端服务 从本地主机可见(就像它绑定到 127.0.0.1 运行 在 Docker 之外),我使用了:

...
.bind(("172.17.0.3",8080))

其中 172.17.0.3 是“docker inspect”命令中显示的 docker 容器的 IP 地址。这很好,似乎是我想要的。虽然不是,因为它仍然通过服务器的外部 IP 地址(使用 run -p 8088:8088 web_api)通过 Internet 进行响应。 (因此,无论我使用已接受的答案还是在 Docker 内的绑定中更具体,都没有关系。因为 docker 仍然有效地向 0.0.0.0 中的每个人开放了 Actix 服务器)。

所以,为了真正完成绑定到 127.0.0.1 的等价物,我 运行 它用

docker run -p 172.17.0.1:8088:8088 web_api

明确指定 Docker 网关 IP 地址。这实现了我正在寻找的东西,一个 Actix 服务器只从本地机器响应 curl http://172.17.0.1:4001——并且特别是 not 响应来自整个网络的 curl http://outside_ip:4001互联网。因此,只要您对 Docker 可能将您的 Actix 服务器暴露在开放的互联网上并不感到惊讶,接受的答案就完全没问题。这样一来,这是一个不同的答案。