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 服务器暴露在开放的互联网上并不感到惊讶,接受的答案就完全没问题。这样一来,这是一个不同的答案。
我正在尝试为我的 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 服务器暴露在开放的互联网上并不感到惊讶,接受的答案就完全没问题。这样一来,这是一个不同的答案。