Dioxus CLI panics with address in use when serving with the `server` platform
Problem
I have this in my dioxus application
use dioxus_dev::{App, routes};
fn main() {
#[cfg(feature = "server")]
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Failed building the Runtime")
.block_on(launch_server());
#[cfg(not(feature = "server"))]
dioxus::launch(App);
}
#[cfg(feature = "server")]
async fn launch_server() {
// use dioxus::fullstack::server::DioxusRouterExt;
use dioxus::prelude::DioxusRouterExt;
use dioxus::prelude::ServeConfigBuilder;
// Connect to dioxus' logging infrastructure
dioxus::logger::initialize_default();
// Connect to the IP and PORT env vars passed by the Dioxus CLI (or your dockerfile)
let socket_addr = dioxus::cli_config::fullstack_address_or_localhost();
// let socket_addr = std::net::SocketAddr::new(
// std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)),
// 8080,
// );
// Build a custom axum router
let router = axum::Router::new()
.nest("/", routes::server_routes())
.serve_dioxus_application(ServeConfigBuilder::new(), App)
.into_make_service();
// And launch it!
let listener = tokio::net::TcpListener::bind(socket_addr).await.unwrap(); // error while unwrapping
axum::serve(listener, router).await.unwrap();
}
where App is a dioxus component with a dioxus router. I am running this code as dioxus fullstack with this command dx serve --platform server. Everything should work fine but I am getting this error
20:40:32 [server] thread 'main' panicked at src/main.rs:44:69:
20:40:32 [server] called `Result::unwrap()` on an `Err` value: Os { code: 98, kind: AddrInUse, message: "Address already in use" }
20:40:31 [dev] Build completed successfully in 838ms, launching app! 💫
20:40:32 [server] stack backtrace:
20:40:32 [server] 0: rust_begin_unwind
20:40:32 [server] at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/panicking.rs:692:5
20:40:32 [server] 1: core::panicking::panic_fmt
20:40:32 [server] at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/panicking.rs:75:14
20:40:32 [server] 2: core::result::unwrap_failed
20:40:32 [server] at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/result.rs:1704:5
20:40:32 [server] 3: core::result::Result<T,E>::unwrap
20:40:32 [server] at /nix/store/drkdxgjrr4mphf4hk2db99pgclq89p7z-rust-default-1.85.0/lib/rustlib/src/rust/library/core/src/result.rs:1109:23
20:40:32 [server] 4: dioxus_dev::launch_server::{{closure}}
20:40:32 [server] at ./src/main.rs:44:20
20:40:32 [server] 5: tokio::runtime::park::CachedParkThread::block_on::{{closure}}
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/runtime/park.rs:284:60
20:40:32 [server] 6: tokio::task::coop::with_budget
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/task/coop/mod.rs:167:5
20:40:32 [server] 7: tokio::task::coop::budget
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/task/coop/mod.rs:133:5
20:40:32 [server] 8: tokio::runtime::park::CachedParkThread::block_on
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/runtime/park.rs:284:31
20:40:32 [dev] Application [server] exited with error: exit status: 101
20:40:32 [server] 9: tokio::runtime::context::blocking::BlockingRegionGuard::block_on
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/runtime/context/blocking.rs:66:9
20:40:32 [server] 10: tokio::runtime::scheduler::multi_thread::MultiThread::block_on::{{closure}}
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/runtime/scheduler/multi_thread/mod.rs:87:13
20:40:32 [server] 11: tokio::runtime::context::runtime::enter_runtime
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/runtime/context/runtime.rs:65:16
20:40:32 [server] 12: tokio::runtime::scheduler::multi_thread::MultiThread::block_on
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/runtime/scheduler/multi_thread/mod.rs:86:9
20:40:32 [server] 13: tokio::runtime::runtime::Runtime::block_on_inner
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/runtime/runtime.rs:358:45
20:40:32 [server] 14: tokio::runtime::runtime::Runtime::block_on
20:40:32 [server] at /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.1/src/runtime/runtime.rs:330:13
20:40:32 [server] 15: dioxus_dev::main
20:40:32 [server] at ./src/main.rs:11:5
20:40:32 [server] 16: core::ops::function::FnOnce::call_once
20:40:32 [server] at /nix/store/drkdxgjrr4mphf4hk2db99pgclq89p7z-rust-default-1.85.0/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
20:40:32 [server] note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
I have nothing running on port 8080. I changed the port to multiple different ports like 8081, still I'm gettting the same error. I am trying to figure this out for 4 days. I couldn't able to find any error related to this. Lsof info
$ lsof -i :8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
dx 5117 sumit 13u IPv4 26511 0t0 TCP *:http-alt (LISTEN)
Environment:
- Dioxus version: v0.6.3, main
- Rust version: 1.87.0, stable
- OS info: NixOS 25.05 (nixpkgs unstable)
- App platform: server
Update on this: I changed my code a little bit to handle the panic
async fn launch_server() {
// use dioxus::fullstack::server::DioxusRouterExt;
use dioxus::prelude::DioxusRouterExt;
use dioxus::prelude::ServeConfigBuilder;
// Connect to dioxus' logging infrastructure
dioxus::logger::initialize_default();
// Connect to the IP and PORT env vars passed by the Dioxus CLI (or your dockerfile)
let socket_addr = dioxus::cli_config::fullstack_address_or_localhost();
// Build a custom axum router
let router = axum::Router::new()
.nest("/", routes::server_routes())
.serve_dioxus_application(ServeConfigBuilder::new(), App)
.into_make_service();
match tokio::net::TcpListener::bind(socket_addr).await {
Ok(listener) => {
println!("Server running on {}", socket_addr);
axum::serve(listener, router).await.unwrap();
}
Err(e) => { // handling panic
eprintln!(
"Failed to bind to {}: {}. Trying a different port.",
socket_addr, e
);
let socket_addr = std::net::SocketAddr::new(
std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)),
8081,
);
let listener = tokio::net::TcpListener::bind(socket_addr).await.unwrap();
println!("Server running on {}", socket_addr);
axum::serve(listener, router).await.unwrap();
// std::process::exit(1);
}
}
}
the server runs at three different ports this time
18:04:21 [dev] Build completed successfully in 927ms, launching app! 💫
18:04:22 [server] Server running on 127.0.0.1:8081
18:04:22 [server] Failed to bind to 192.168.29.153:40213: Address already in use (os error 98). Trying a different port.
18:04:22 [server] Server running on 192.168.29.153:40213
It runs at port 127.0.0.1:8081, 192.168.29.153:40213 and 127.0.0.1:8080.
I think this has more to do with the dx serve --platform server command than your axum integration code. You can get the same error after cloning dioxus and with the launch server entry point:
cd packages/playwright-tests
cargo run --package dioxus-cli -- serve --platform server
In general, you should use the web platform that builds both the client and server side of the application at the same time
Doing dx serve --platform web doesn't compile. It is giving me a lot of errors. I can't paste all of that here. A smaller part:
19:58:20 [cargo] error: could not compile `mio` (lib) due to 47 previous errors
19:58:20 [cargo] Caused by:
19:58:20 [cargo] process didn't exit successfully: `rustc --crate-name mio --edition=2021 /home/sumit/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mio-1.0.3/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C opt-level=1 -C embed-bitcode=no -C debuginfo=2 --warn=unexpected_cfgs --check-cfg 'cfg(mio_unsupported_force_poll_poll)' --check-cfg 'cfg(mio_unsupported_force_waker_pipe)' -C debug-assertions=on --cfg 'feature="net"' --cfg 'feature="os-ext"' --cfg 'feature="os-poll"' --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values("default", "log", "net", "os-ext", "os-poll"))' -C metadata=a1fd621ffe65b85b -C extra-filename=-12f91ec8a037f039 --out-dir /home/sumit/dev/test/dioxus-dev/target/wasm32-unknown-unknown/wasm-dev/deps --target wasm32-unknown-unknown -L dependency=/home/sumit/dev/test/dioxus-dev/target/wasm32-unknown-unknown/wasm-dev/deps -L dependency=/home/sumit/dev/test/dioxus-dev/target/wasm-dev/deps --cap-lints allow` (exit status: 1)
19:58:20 [cargo] warning: build failed, waiting for other jobs to finish...
I have uploaded my code in this repository https://github.com/fasttaps/dioxus-dev for you to check. I use nixos so is it a flake problem? It used to compile without any errors in web platform. And I haven't added any #[cfg(not(feature = "server"))] in any components.
Doing
dx serve --platform webdoesn't compile. It is giving me a lot of errors.
You need to make all of your server-only dependencies optional and only enable them when the server feature is enabled as documented here
Doing
dx serve --platform webdoesn't compile. It is giving me a lot of errors.You need to make all of your server-only dependencies optional and only enable them when the server feature is enabled as documented here
Hey I have one more question. When we are using #[server] macro, is dioxus creating an endpoint? And if it isn't then how the frontend is calling the backend rpc? I created a button to get data from server but when I am clicking the button only a js file is coming from this route http://127.0.0.1:8080/api/img_list16770050977829801849. Is this route automatically created by dioxus?
And does this route changes with every rebuild of our application
Hey I have one more question. When we are using
#[server]macro, is dioxus creating an endpoint? And if it isn't then how the frontend is calling the backend rpc? I created a button to get data from server but when I am clicking the button only a js file is coming from this routehttp://127.0.0.1:8080/api/img_list16770050977829801849. Is this route automatically created by dioxus? And does this route changes with every rebuild of our application
Yes it creates an endpoint. By default it uses a hash based on the contents + location of the macro, but you can override the endpoint with #[server(endpoint = "/your/router")]
Okay. Thanks for your help!