I使用Axum和Supabase作为DB选择,在Rust中进行了网络后端。我从中制作了一个Docker映像,并尝试运行一个容器,但是我一直遇到此错误:
以连接到数据库:io(OS {代码:101,KIND:NetworkUnreach,消息,消息:“网络是无法到达的”})
我相信我使用Docker组成的所有必需的环境变量。我不确定问题是什么。
i我尝试从容器内部ping我的数据库URI字符串,但失败了。为了确保这不是连接问题,我在Google上播放并通过了。同样,仅供参考,supabase db并没有自我托管。它来自Supabase Cloud Service。从其他论坛中说,这可能是DNS解决问题
{
"builder": {
"features": {
"buildkit": true
},
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"dns": [
"8.8.8.8",
"8.8.4.4"
],
"experimental": false
}
2025-03-15 15:50:49 warning: ra-backend v0.1.0 (/usr/src/app) ignoring invalid dependency `cargo-watch` which is missing a lib target
2025-03-15 15:50:49 warning: variant `ServerError` is never constructed
2025-03-15 15:50:49 --> src/utils/error.rs:24:5
2025-03-15 15:50:49 |
2025-03-15 15:50:49 19 | pub enum ErrorMessage {
2025-03-15 15:50:49 | ------------ variant in this enum
2025-03-15 15:50:49 ...
2025-03-15 15:50:49 24 | ServerError,
2025-03-15 15:50:49 | ^^^^^^^^^^^
2025-03-15 15:50:49 |
2025-03-15 15:50:49 = note: `ErrorMessage` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
2025-03-15 15:50:49 = note: `#[warn(dead_code)]` on by default
2025-03-15 15:50:49
2025-03-15 15:50:49 warning: methods `verifed_token` and `add_verifed_token` are never used
2025-03-15 15:50:49 --> src/services/database.rs:56:14
2025-03-15 15:50:49 |
2025-03-15 15:50:49 20 | pub trait UserActions {
2025-03-15 15:50:49 | ----------- methods in this trait
2025-03-15 15:50:49 ...
2025-03-15 15:50:49 56 | async fn verifed_token(&self, token: &str) -> Result<(), sqlx::Error>;
2025-03-15 15:50:49 | ^^^^^^^^^^^^^
2025-03-15 15:50:49 57 |
2025-03-15 15:50:49 58 | async fn add_verifed_token(
2025-03-15 15:50:49 | ^^^^^^^^^^^^^^^^^
2025-03-15 15:50:49
2025-03-15 15:50:49 warning: `ra-backend` (lib) generated 2 warnings
2025-03-15 15:50:49 Finished `release` profile [optimized] target(s) in 0.16s
2025-03-15 15:50:49 Running `target/release/ra-backend`
2025-03-15 15:50:49 Failed to connect to the database: Io(Os { code: 101, kind: NetworkUnreachable, message: "Network is unreachable" })
上面是直接从Docker Desktop取的Docker容器的日志。有关更多上下文,以下是dockerfile
FROM rust:latest
WORKDIR /usr/src/app
RUN apt-get update && apt-get install -y \
libssl-dev \
pkg-config \
build-essential \
&& rm -rf /var/lib/apt/lists/*
ENV SQLX_OFFLINE=true
COPY . .
RUN cargo install sqlx-cli --no-default-features --features postgres
RUN cargo build --release
EXPOSE 8080
CMD cargo run --release
为了进一步调试,这是运行我的API的代码。
use std::sync::Arc;
use api::create_api;
use axum::{http::{header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE}, HeaderValue, Method}, routing::get, Json};
use config::Config;
use dotenvy::dotenv;
use services::database::DBClient;
use sqlx::postgres::PgPoolOptions;
use tokio::net::TcpListener;
use tower_http::cors::CorsLayer;
use tracing_subscriber::filter::LevelFilter;
mod models;
mod utils;
mod config;
mod services;
mod routes;
mod api;
#[derive(Debug, Clone)]
pub struct AppState {
pub env: Config,
pub db_client: DBClient
}
pub async fn run()
{
tracing_subscriber::fmt()
.with_max_level(LevelFilter::DEBUG)
.init();
dotenv().ok();
let config = Config::init();
let pool = match PgPoolOptions::new()
.max_connections(10)
.connect(&config.database_url)
.await
{
Ok(pool) => {
println!("Connection to the database is successful");
pool
}
Err(err) => {
println!("Failed to connect to the database: {:?}", err);
std::process::exit(1);
}
};
let cors = CorsLayer::new()
.allow_origin("0.0.0.0:8080".parse::<HeaderValue>().unwrap())
.allow_headers([AUTHORIZATION, ACCEPT, CONTENT_TYPE])
.allow_credentials(true)
.allow_methods([Method::GET, Method::POST, Method::PUT]);
let db_client = DBClient::new(pool);
let app_state = AppState {
env: config.clone(),
db_client
};
let app = create_api(Arc::new(app_state.clone()))
.route("/", get(|| async {Json("Hello, World!")}))
.layer(cors.clone());
println!("Server running on 0.0.0.0:{}", config.port);
let listener = TcpListener::bind(format!("0.0.0.0:{}", config.port))
.await
.unwrap();
println!("Listening on: {}", listener.local_addr().unwrap());
axum::serve(listener, app).await.unwrap();
}
这一点。我不知道会导致这一点。帮助您表示赞赏。 这是Docker组成的文件
services:
ra-backend:
container_name: ra-backend
image: kingdawnage/ra-backend:1.0.0
build: .
ports:
- "8080:8080"
# command: ["sleep", "infinity"]
environment:
- DATABASE_URL=${DATABASE_URL}
- JWT_SECRET=${JWT_SECRET}
- JWT_MAXAGE=${JWT_MAXAGE}
Edit1:添加了Docker组成文件
okay,我花了一段时间才弄清楚答案,但事实证明,supabase与他们的数据库有三种连接方法。
直接连接:非常适合具有持久,长寿连接的应用,例如在虚拟机或长期存在的容器上运行的连接。 transaction Pooler:适合无状态应用程序(如无服务器功能)的理想选择,其中每次与Postgres的互动都是简短而隔离的。
SessionPooler:通过IPv4网络连接时仅建议作为直接连接的替代方案。建立一个支持IPv6的网络,如果您想使用直接连接URI字符串。