Rust TCP Server in Docker Container Not Working

Viewed 30

I'm struggling to understand why the tcp server can't accept outside requests.

My Server:

use std::io::Write;
use std::net::TcpListener;
use std::thread;

fn main() {
    let listener = TcpListener::bind("0.0.0.0:8080").unwrap();
    println!("listening started, ready to accept");
    for stream in listener.incoming() {
        thread::spawn(|| {
            let mut stream = stream.unwrap();
            stream.write(b"Hello World\r\n").unwrap();
        });
    }
}

Docker File

FROM rust:1.31

WORKDIR /usr/src/proto-rust
COPY . .

RUN cargo install --path .

EXPOSE 8080

CMD ["cargo", "run"]

Running Locally, this works

nc 0.0.0.0 8080

After running the following:

docker run --rm -p 8080:8080 --name my-running-app proto-rust

and checking the docker bridge

docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "78d335687fcd96ad1051ca17662024708dff9db4d3043b787a43d29edbb8ff58",
        "Created": "2022-09-03T01:53:48.606052848Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "21a4f5fec2cb2a880ed01c044ccaf001e120c9b507d34fabf93c9da21957d558": {
                "Name": "my-running-app",
                "EndpointID": "34a003ea12612d479e47a61478f3a445455f919a66350b9b5fde651e6cb8a12b",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

Running either of the following does not work:

nc 172.17.0.2 8080
nc localhost 8080

I'm not sure where to go from here. I think my ip address for the docker container is wrong because netcat can't see the open port? I'm not sure here. Why do I even need the extra address as well as the network bridge? It's wild docker can't just expose on localhost.

1 Answers

I had originally made the server 127.0.0.1, and then changed it to 0.0.0.0 after since docker only binds on localhost. However, I did not run docker build, which meant the update never applied to the docker image. After running

docker build -t proto-rust . 

the following works:

nc localhost 8080
Related