【问题标题】:Rust actix_web inside docker isn't attainable, why?docker 中的 Rust actix_web 无法实现,为什么?
【发布时间】:2022-03-31 06:53:18
【问题描述】:

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

Dockerfile

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"]}

外界有什么问题?

【问题讨论】:

    标签: docker rust rust-actix


    【解决方案1】:

    如果您像我一样并按照 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();
    }
    

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

    【讨论】:

    • 我遵循了 actix-web 的入门指南,最终到达the autreload section。它建议使用systemfd --no-pid -s http::3000 -- cargo watch -x run,需要将其更改为http::0.0.0.0:3000才能绑定到所有接口。
    • 是否会有一些.bind("host.docker.internal:8088") 的变体实际上可以工作——并且对只有真正的本地主机能够访问 Actix 保持相同的限制?这不起作用,也不能绑定到 Docker 网关 IP。
    【解决方案2】:

    为了完成约翰所说的,在我的例子中,我必须使用一个元组:.bind( ("0.0.0.0", 8088) )

    【讨论】:

    • 这不是答案,应该是对已批准答案的评论。
    • @hB0 我希望我可以,但 cmets 只对拥有 50 声望的用户可用。
    【解决方案3】:

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

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

    其中 172.17.0.3 是“docker inspect”命令中显示的 docker 容器的 IP 地址。这很好,似乎是我想要的。不是因为它仍然通过互联网从服务器的外部 IP 地址响应(使用run -p 8088:8088 web_api)。 (所以如果我使用接受的答案或者更具体地在 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--特别是 从互联网上响应 curl http://outside_ip:4001。因此,只要您对 Docker 可能将您的 Actix 服务器暴露在开放的互联网上并不感到惊讶,那么接受的答案就完全没问题。这样一来,这是一个不同的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多