You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署Rust Actix服务出现404错误的排查求助

Docker部署Rust Actix Web服务出现404错误排查

我在Docker中部署基于Rust Actix框架开发的Web服务时出现404错误,但本地运行该服务一切正常。近2-3天来仅在Docker环境中出现此问题,其他容器运行均正常。执行sudo docker compose up时仅出现一条my-app警告,构建完成。以下是相关配置及代码,恳请帮忙排查问题:

Dockerfile

# Build stage
FROM rust:slim-buster as builder

RUN apt-get update && \
  apt-get install -y pkg-config make g++ libssl-dev cmake libmariadb-dev-compat openssl && \
  rustup target add x86_64-unknown-linux-gnu

WORKDIR /var/www/app

COPY . .

RUN cargo build
# Prod stage, removing the Rust toolchain
FROM gcr.io/distroless/cc
COPY --from=builder /var/www/app/config /config
COPY --from=builder /var/www/app/target/debug/my-app /

CMD ["./my-app"]

docker-compose.yml

version: '3.9'

services:
  
  my-app:
    container_name: my-app
    image: my-app
    build: .
    ports:
      - '8088:8088'
    expose:
      - '8088'
    depends_on:
      - redis
      - mosquitto
      - db

  redis:
    container_name: redis
    image: "redis:latest"
    ports:
      - "6379:6379"
    expose:
      - "6379"
    
  mosquitto:
    image: eclipse-mosquitto:2.0.15
    container_name: mosquitto
    user: mosquitto
    volumes:
      - type: bind
        source: ./config/
        target: /mosquitto/config/
    # - type: bind
    #   source: ./log/
    #   target: /mosquitto/log/
      - type: volume
        source: data
        target: /mosquitto/data
    ports:
      - target: 1883
        published: 1883
        protocol: tcp
        mode: host
      - target: 9001
        published: 9001
        protocol: tcp
        mode: host
  
  db:
    container_name: sqlite3
    image: nouchka/sqlite3:latest
    stdin_open: true
    tty: true
    volumes:
      #Modify following line
      - ./config/isumis.db:/config
    ports:
      - '9000:9000' # expose ports - HOST:CONTAINER
    expose:
      - '9000'
    restart: unless-stopped

  mobsf:
    container_name: mobsf
    build: https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
    image: mobsf
    ports:
      - "8000:8000"
    expose:
      - "8000"

  nodejs:
    container_name: blacklight-collector
    image: isumis/blacklight
    build: 
      context: ./blacklight-config/
    ports:
      - "8081:8081"
    expose:
      - "8081"
    
volumes:
  data:
    name: "mqtt-broker-data"

Actix服务代码

pub async fn server() -> Result<(), impl Error> {
    info!("Start backend!");

    init();
    let store: Data<DataStore> = Data::new(DataStore::default());
    info!("Swagger UI available at http://localhost:8088/api/ and http://localhost:8088/clm-core/");

    // Init actix
    HttpServer::new(move || {
        App::new()
            .wrap(Logger::default())
            .configure(data_controller::configure(store.clone()))
            .service(
                SwaggerUi::new("/api/{_:.*}")
                    .url("/api-docs/openapi.json", ApiDoc::openapi().clone()),
            )
            .service(
                SwaggerUi::new("/clm-core/{_:.*}")
                    .external_url_unchecked("http://localhost:3006/core/swagger", json!({"openapi": "3.0.0"})),
            )
            .service(
                web::scope("/dashboard/user")
                    .service(get_user_by_id)
                    //.service(get_user_data)
            )
            .service(
                web::scope("/dashboard")
                    .service(get_all_statistics)
                    //.service(get_specific_statistics)
                    .service(static_scan)
            )
            .service(
                web::scope("/tools")
                    .service(blacklight)
                    .service(port_scanner)
                    .service(analyze_ip)
            )
            .service(
                web::scope("/init")
                    .service(create_test_user)
                    .service(api_key)
            )
    })
    .bind(("0.0.0.0", 8088))?
    .run()
    .await
}

fn init() {
    // Connect to redis
    redis_service::init();

    thread::spawn(|| {
        // Wait for new messages
        crate::service::subscriber_service::subscriber();
    });
}

依赖配置

bench = []
test = []
example = []

[[bin]]
path = "src/main.rs"
name = "my-app"
test = false
doctest = false
bench = false
doc = false
plugin = false
proc-macro = false
harness = true
edition = "2021"
required-features = []

[package]
name = "my-app"
edition = "2021"
version = "0.0.1"
autobins = false
autoexamples = false
autotests = false
autobenches = false

[profile.release]
lto = true
opt-level = "z"
debug = true
strip = true

[profile.dev]
debug = 2

[dependencies]
actix-web = "4"
async-std = "1.12.0"
cfonts = "1"
futures = "*"
isocountry = "0.3.2"
lazy_static = "*"
log = "0.4"
paho-mqtt = "0.12.1"
r2d2 = "0.8.10"
regex = "1"
serde_json = "1"
simple_logger = "*"
whois-rust = "1.5.1"
rand = "0.8.5"
dns-lookup = "2.0.2"

[dependencies.attohttpc]
version = "0.26.0"
features = ["json"]

[dependencies.redis]
version = "0.23.1"
features = ["r2d2"]

[dependencies.serde]
version = "1.0"
features = ["derive"]

[dependencies.utoipa]
version = "3.4.4"
features = ["actix_extras"]

[dependencies.utoipa-swagger-ui]
version = "3.1.5"
features = ["actix-web"]

启动时的警告信息

[+] Running 1/1
 ! my-app Warning                                                        1.5s 
[+] Building 93.0s (14/14) FINISHED

排查方向及解决方案

  • 镜像构建优化
    当前Dockerfile构建的是debug版本,拷贝的是target/debug/my-app。debug版本可能存在路径依赖或动态库缺失问题,建议切换为release版本:
    修改Dockerfile中的构建命令为RUN cargo build --release,同时将拷贝路径改为/var/www/app/target/release/my-app。distroless镜像精简,release版本对依赖的要求更低,更适合生产环境。

  • 端口与网络验证

    1. 进入容器检查服务监听状态:如果distroless镜像缺少netstat,可临时替换为ubuntu:latest镜像调试,执行netstat -tulpn确认服务绑定0.0.0.0:8088。
    2. 宿主机执行netstat -tulpn | grep 8088,确认端口映射已生效。
  • 配置文件校验
    进入容器执行ls /config,确认配置文件完整且权限正常。检查服务代码中读取配置的路径是否指向容器内的/config,避免本地相对路径在容器内失效。

  • 依赖服务就绪问题
    depends_on仅保证容器启动顺序,不保证服务就绪。Redis、DB等服务可能未完全启动导致Actix初始化失败,路由未注册:
    在docker-compose.yml的my-app服务中添加健康检查,等待服务就绪:

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8088/init/api_key"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 30s
    
  • 日志分析
    执行docker logs my-app查看服务启动日志,检查是否存在Redis连接失败、数据库加载错误等初始化异常,这些问题会导致路由未正确注册从而返回404。同时可升级Actix日志级别,添加详细请求日志,确认请求路径是否匹配路由规则。

内容的提问来源于stack exchange,提问作者Jan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:08:08