An Actix-Web application in an Ubuntu Docker container may not be accessible from the host operating system. For non-production codes and configuration, it may be due to two factors.
Actix-Web Is Not Accessible in Docker Container Due to Rust Codes
The first factor may be due to our codes. They bind to a specific IP address. Consider the following Rust codes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | use actix_web::{App, get, HttpServer, Responder, HttpResponse}; #[get("/")] async fn index() -> impl Responder { HttpResponse::Ok() .content_type("text/html") .body("<html><head><title>Welcome - Turreta.com</title></head><body><h1>Index page - Turreta.com</h1></body></html>") } #[actix_rt::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| App::new() .service(index) ) .bind("127.0.0.1:8080")? .run() .await } |
The codes bind the server to 127.0.0.1 (localhost). This is fine when we are not deploying to a virtual machine. Otherwise, the application will not be accessible from outside the Docker container because the application expects requests from within the container.
To fix this problem, consider binding the server to 0.0.0.0. This makes the application to expect requests from any IP address. For production deployment, bind the server to the host operating system IP address.
1 2 3 4 5 6 7 8 9 10 | #[actix_rt::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| App::new() .service(index) ) // .bind("127.0.0.1:8080")? .bind(("0.0.0.0",8080))? .run() .await } |
Using EXPOSE in Docker File
Another factor that may make an Actix-Web program running in an Ubuntu Docker container not accessible is when we specify EXPOSE in our DockerFile. Consider the following DockerFile.
1 2 3 4 5 6 7 8 9 10 11 12 | FROM ubuntu:18.04 RUN apt-get update && apt-get install -y curl RUN apt-get install build-essential -y RUN mkdir -p /actix-web/www WORKDIR /actix-web/www COPY target/debug/actix-web-docker /actix-web/www/actix-web-docker EXPOSE 8080 CMD ./actix-web-docker |
To fix the problem, comment out the EXPOSE instruction. Use the docker run --publish (or -p ) flag to explicitly specify the host-container ports. The following is a modified DockerFile.
1 2 3 4 5 6 7 8 9 10 11 12 | FROM ubuntu:18.04 RUN apt-get update && apt-get install -y curl RUN apt-get install build-essential -y RUN mkdir -p /actix-web/www WORKDIR /actix-web/www COPY target/debug/actix-web-docker /actix-web/www/actix-web-docker # EXPOSE 8080 - Don't use this if you want the web server accessible from the Windows host CMD ./actix-web-docker |
We may need to build the Ubuntu Docker image again.
1 | docker build -t turreta-rust-actix-web-env:1.0 . |
Then, we start the Ubuntu Docker container using the following command.
1 | docker run --rm -p 8181:8080 --name actix-web-env turreta-rust-actix-web-env:1.0 |
There may be other ways to fix the inaccessibility issue but this post is based on the experience of Deploy Actix-Web In Docker Container.