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

React+Docker部署下APK下载异常:下载文件为index.html问题求助

问题排查:APK下载返回index.html而非目标文件

问题描述

开发Web/移动端项目时,点击下载按钮本应获取移动端APK,但实际下载的是当前页面的index.html。项目采用Docker镜像+Docker Compose部署,包含Flutter构建APK的镜像和React前端构建运行镜像。

相关配置

Docker Compose文件

version: "3.9"
services:
  client_mobile:
    build: ./flutter
    volumes:
      - apk-volume:/app/client
  web:
    build: ./front-web
    env_file:
      - ./front-web/.env
    ports:
      - "8081:3000"
    depends_on:
      - client_mobile
    restart: always
    volumes:
      - apk-volume:/app/client

volumes:
  apk-volume:

Flutter Dockerfile

FROM androidsdk/android-30

# Install flutter
RUN apt-get update
RUN apt-get install -y bash git unzip wget
RUN apt-get clean
WORKDIR /
RUN git clone https://github.com/flutter/flutter.git
ENV PATH "$PATH:/flutter/bin"
ENV FLUTTER_PATH /flutter/
RUN flutter upgrade
RUN flutter precache

# Install gradle
RUN wget https://services.gradle.org/distributions/gradle-7.3.3-bin.zip
RUN mkdir /opt/gradle
RUN unzip -d /opt/gradle gradle-7.3.3-bin.zip
ENV PATH "$PATH:/opt/gradle/gradle-7.3.3/bin"
RUN rm gradle-7.3.3-bin.zip

RUN mkdir -p /app/android
RUN echo "sdk.dir=$ANDROID_SDK" >> /app/android/local.properties
RUN echo "flutter.sdk=$FLUTTER_PATH" >> /app/android/local.properties
RUN echo "flutter.buildMode=debug" >> /app/android/local.properties
RUN echo "flutter.versionName=1.0.0" >> /app/android/local.properties
RUN echo "flutter.versionCode=1" >> /app/android/local.properties

WORKDIR /app/android
COPY ./ /app/

RUN gradle --refresh-dependencies
RUN flutter build apk --release

CMD mv ../build/app/outputs/apk/release/app-release.apk /app/client/app-release.apk

React Dockerfile

FROM node AS builder

WORKDIR /usr/src/app

COPY ./package.json /usr/src/app/

RUN cd /usr/src/app; npm install -g npm@latest; npm install

COPY ./  /usr/src/app/

RUN cd /usr/src/app; npm run build

FROM builder

WORKDIR /usr/src/app

COPY --from=builder /usr/src/app/build /usr/src/app/build

RUN npm install -g serve

EXPOSE 3000

CMD ["serve", "-s", "build", "-l", "3000"]

React下载代码

<a href='/app/client/area_mobile.apk' download style={{textDecoration: "none"}}>
  <div className='userPanel__sideBar__rows__row'>
    <div style={{marginRight: "5%", marginTop: "2%"}}>
      <DownloadIcon />
    </div>
    <p>Download Mobile</p>
  </div>
</a>

问题原因分析

  1. 文件名不匹配:Flutter镜像生成的APK文件名是app-release.apk,但React代码里请求的是area_mobile.apk,目标文件不存在。
  2. 静态资源路径未映射:React用serve -s build启动,-s开启单页应用模式,当请求路径不存在时会返回index.html。而APK所在的/app/client目录并未被配置为serve的静态资源目录,导致请求该路径时serve无法找到文件,直接返回index.html。
  3. 容器卷挂载位置错误:React容器将apk-volume挂载到/app/client,但serve的根目录是/usr/src/app/build,该挂载目录不在serve的静态资源扫描范围内,前端无法访问到APK文件。

解决方案

1. 统一APK文件名

修改Flutter Dockerfile的CMD命令,将生成的APK重命名为前端请求的文件名:

CMD mv ../build/app/outputs/apk/release/app-release.apk /app/client/area_mobile.apk

2. 调整React容器的静态资源配置

方案一:将APK目录挂载到serve的静态资源根目录下

修改Docker Compose中web服务的volumes配置,把apk-volume挂载到React build目录下的子目录(比如apk):

services:
  web:
    # 保留其他原有配置
    volumes:
      - apk-volume:/usr/src/app/build/apk

同时修改React下载代码的href路径:

<a href='/apk/area_mobile.apk' download style={{textDecoration: "none"}}>
  {/* 保留原有内容 */}
</a>

方案二:修改serve命令,添加额外静态资源目录

如果不想挂载到build目录,可以修改React Dockerfile的CMD,让serve同时扫描build目录和APK目录:

# 注意:去掉-s参数会影响单页应用路由,若项目是单页应用,优先选方案一
CMD ["serve", "-l", "3000", "build", "/app/client"]

若需保留单页应用模式,推荐使用Nginx替代serve部署React,通过Nginx配置文件映射APK目录的静态资源,配置示例:

server {
    listen 3000;
    root /usr/src/app/build;
    index index.html;

    # 处理单页应用路由
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 映射APK目录
    location /apk/ {
        alias /app/client/;
    }
}

3. 验证APK生成与挂载

确认client_mobile服务已正确生成APK并写入卷中:

# 查看client_mobile服务日志,确认APK生成成功
docker-compose logs client_mobile
# 进入web容器,检查APK是否存在
docker-compose exec web ls /app/client

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:05:14