构建用于 Flutter 构建环境的 Docker 容器失败,出现连接错误。

huangapple go评论117阅读模式
英文:

Building a docker container for flutter build environment fails with connectivity errors

问题

我会翻译代码部分的内容,以下是您提供的代码的翻译:

  1. # 示例用法:
  2. # 使用以下命令构建镜像:
  3. # docker build --pull --rm -f 'Dockerfile' -t flutter_build:latest .
  4. # --pull 尝试始终拉取新镜像
  5. # --rm 在构建后删除中间生成的容器
  6. # -f 指定要构建镜像的文件
  7. # -t 设置一个标签为“label_of_container:with_version”
  8. # 运行容器:
  9. # docker run -p 8080:80 flutter_build
  10. # -p 将内部端口80映射到外部/公共端口8080 -> 访问 http://localhost:8080
  11. ARG WORKDIR=/app
  12. # 构建Flutter Web应用程序
  13. FROM ubuntu:latest AS FLUTTER_BUILDER
  14. ARG WORKDIR
  15. ARG USER_NAME=flutter
  16. ARG REPO_NAME=flutter
  17. ARG BRANCH_NAME=stable
  18. RUN apt update -y
  19. RUN apt install -y bash curl file git unzip zip xz-utils libglu1-mesa
  20. # 使用ADD命令绕过缓存此Docker层,每当新的Flutter版本发布到stable时都会触发
  21. ADD https://api.github.com/repos/${USER_NAME}/${REPO_NAME}/git/refs/heads/${BRANCH_NAME} ${REPO_NAME}_${BRANCH_NAME}_version.json
  22. RUN git clone https://github.com/${USER_NAME}/${REPO_NAME}.git -b ${BRANCH_NAME}
  23. ENV PATH="$PATH:/flutter/bin"
  24. RUN flutter precache
  25. COPY . ${WORKDIR}
  26. WORKDIR ${WORKDIR}
  27. RUN flutter clean
  28. RUN flutter pub get
  29. RUN flutter build web
  30. # 提供Flutter Web应用程序
  31. FROM nginx:latest
  32. ARG WORKDIR
  33. EXPOSE 80
  34. COPY --from=FLUTTER_BUILDER ${WORKDIR}/build/web /usr/share/nginx/html

请注意,这只是您提供的Dockerfile的翻译部分。如果您需要有关如何修复Docker容器中的Flutter问题的更多信息,请提供相关上下文。

英文:

I'm trying to setup an easy docker container with flutter installed in it. One of the commands I'm using in a RUN statement is flutter precache which somehow fails with the following error:

  1. flutter precache -v
  2. Downloading Linux arm64 Dart SDK from Flutter engine ada363ee93b17cfe31587b5102679885cb40837e...
  3. % Total % Received % Xferd Average Speed Time Time Time Current
  4. Dload Upload Total Spent Left Speed
  5. 100 139M 100 139M 0 0 10.6M 0 0:00:13 0:00:13 --:--:-- 10.8M
  6. Building flutter tool...
  7. [ +7 ms] Unable to locate an Android SDK.
  8. [ +2 ms] executing: uname -m
  9. [ +2 ms] Exit code 0 from: uname -m
  10. [ ] aarch64
  11. [ ] executing: [/flutter/] git -c log.showSignature=false log -n 1 --pretty=format:%H
  12. [ +3 ms] Exit code 0 from: git -c log.showSignature=false log -n 1 --pretty=format:%H
  13. [ ] 12cb4eb7a009f52b347b62ade7cb4854b926af72
  14. [ ] executing: [/flutter/] git tag --points-at 12cb4eb7a009f52b347b62ade7cb4854b926af72
  15. [ +15 ms] Exit code 0 from: git tag --points-at 12cb4eb7a009f52b347b62ade7cb4854b926af72
  16. [ ] 3.7.6
  17. [ +4 ms] executing: [/flutter/] git rev-parse --abbrev-ref --symbolic @{upstream}
  18. [ +3 ms] Exit code 0 from: git rev-parse --abbrev-ref --symbolic @{upstream}
  19. [ ] origin/stable
  20. [ ] executing: [/flutter/] git ls-remote --get-url origin
  21. [ +3 ms] Exit code 0 from: git ls-remote --get-url origin
  22. [ ] https://github.com/flutter/flutter.git
  23. [ +10 ms] executing: [/flutter/] git rev-parse --abbrev-ref HEAD
  24. [ +3 ms] Exit code 0 from: git rev-parse --abbrev-ref HEAD
  25. [ ] stable
  26. [ +25 ms] Downloading Material fonts...
  27. [ +32 ms] HandshakeException: Connection terminated during handshake
  28. [ +10 ms] Downloading Material fonts... (completed in 32ms)
  29. [ ] Downloading Material fonts...
  30. [ +18 ms] HandshakeException: Connection terminated during handshake
  31. [ ] Downloading Material fonts... (completed in 18ms)
  32. [ ] "flutter precache" took 93ms.
  33. [ +3 ms] Failed to download https://storage.googleapis.com/flutter_infra_release/flutter/fonts/3012db47f3130e62f7cc0beabff968a33cbec8d8/fonts.zip. Ensure you
  34. have
  35. network connectivity and then try again.
  36. HandshakeException: Connection terminated during handshake
  37. [ +1 ms]
  38. #0 throwToolExit (package:flutter_tools/src/base/common.dart:10:3)
  39. #1 ArtifactUpdater._downloadArchive (package:flutter_tools/src/cache.dart:1062:11)
  40. <asynchronous suspension>
  41. #2 CachedArtifact.update (package:flutter_tools/src/cache.dart:810:5)
  42. <asynchronous suspension>
  43. #3 Cache.updateAll (package:flutter_tools/src/cache.dart:677:9)
  44. <asynchronous suspension>
  45. #4 PrecacheCommand.runCommand (package:flutter_tools/src/commands/precache.dart:168:7)
  46. <asynchronous suspension>
  47. #5 FlutterCommand.run.<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1257:27)
  48. <asynchronous suspension>
  49. #6 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
  50. <asynchronous suspension>
  51. #7 CommandRunner.runCommand (package:args/command_runner.dart:209:13)
  52. <asynchronous suspension>
  53. #8 FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:283:9)
  54. <asynchronous suspension>
  55. #9 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
  56. <asynchronous suspension>
  57. #10 FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:229:5)
  58. <asynchronous suspension>
  59. #11 run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:64:9)
  60. <asynchronous suspension>
  61. #12 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
  62. <asynchronous suspension>
  63. #13 main (package:flutter_tools/executable.dart:91:3)
  64. <asynchronous suspension>
  65. [ +1 ms] ensureAnalyticsSent: 0ms
  66. [ ] Running 0 shutdown hooks
  67. [ ] Shutdown hooks complete
  68. [ ] exiting with code 1
  1. Failed to download https://storage.googleapis.com/flutter_infra_release/flutter/fonts/3012db47f3130e62f7cc0beabff968a33cbec8d8/fonts.zip. Ensure you have
  2. network connectivity and then try again.
  3. HandshakeException: Connection terminated during handshake

Executing flutter precache a second time in an interactive container (shell attached) works instantly. Any idea how to prevent/fix this error?

I already tried running the docker build with --network=host or adding things like update-ca-certificates inside the container but nothing works. Also ignoring the error and adding a second RUN flutter precache in the dockerfile doesn't work (ignoring by using RUN flutter precache; exit 0 as the first RUN)

How could I fix this?

PS: The Dockerfile I'm currently using to build a flutter build environment on MacBook Pro M1 looks like this:

  1. # Example Usage:
  2. # Build the image with:
  3. # docker build --pull --rm -f 'Dockerfile' -t flutter_build:latest .
  4. # --pull tries to always pull new images
  5. # --rm delete intermediate generated containers after build
  6. # -f specifies the file to build the image
  7. # -t sets a label_of_container:with_version
  8. #
  9. # Run it with:
  10. # docker run -p 8080:80 flutter_build
  11. # The -p exposes the internal port 80 to the
  12. # external/public port 8080 -> visit http://localhost:8080
  13. ARG WORKDIR=/app
  14. # build the flutter web app
  15. FROM ubuntu:latest AS FLUTTER_BUILDER
  16. ARG WORKDIR
  17. ARG USER_NAME=flutter
  18. ARG REPO_NAME=flutter
  19. ARG BRANCH_NAME=stable
  20. RUN apt update -y
  21. RUN apt install -y bash curl file git unzip zip xz-utils libglu1-mesa
  22. # using ADD here to bypass caching of this docker layer whenever a new flutter version was released to stable
  23. ADD https://api.github.com/repos/${USER_NAME}/${REPO_NAME}/git/refs/heads/${BRANCH_NAME} ${REPO_NAME}_${BRANCH_NAME}_version.json
  24. RUN git clone https://github.com/${USER_NAME}/${REPO_NAME}.git -b ${BRANCH_NAME}
  25. ENV PATH="$PATH:/flutter/bin"
  26. RUN flutter precache
  27. COPY . ${WORKDIR}
  28. WORKDIR ${WORKDIR}
  29. RUN flutter clean
  30. RUN flutter pub get
  31. RUN flutter build web
  32. # serve the flutter web app
  33. FROM nginx:latest
  34. ARG WORKDIR
  35. EXPOSE 80
  36. COPY --from=FLUTTER_BUILDER ${WORKDIR}/build/web /usr/share/nginx/html

答案1

得分: 2

以下是代码部分的翻译:

  1. # 全局设置工作目录(仍然需要在每个阶段中引用!)
  2. ARG WORKDIR=/app
  3. # 构建 Flutter Web 应用程序
  4. #
  5. # 在第一个阶段中,只需准备一个 Ubuntu 容器
  6. # 并安装 Flutter 工具以构建 Flutter 应用程序
  7. FROM ubuntu:latest AS FLUTTER_BUILDER
  8. # 设置工作目录
  9. ARG WORKDIR
  10. # 设置从中克隆 Flutter SDK 的 GitHub 存储库信息。
  11. ARG USER_NAME=flutter
  12. ARG REPO_NAME=flutter
  13. ARG BRANCH_NAME=stable
  14. # 使用所需的所有工具准备 Ubuntu 容器
  15. RUN apt update -y
  16. RUN apt install -y bash curl file git unzip zip xz-utils libglu1-mesa
  17. # 有时 Google 服务器响应稍慢,导致握手失败
  18. # 增加超时时间可以解决这个错误!
  19. ENV HTTP_TIMEOUT=5000
  20. # 在这里,我们使用 ADD 来在以下 Docker 阶段中使缓存无效,当给定的 Flutter GitHub 存储库的给定分支上有新的提交/版本时 - 注意:这取决于 GitHub API!
  21. ADD https://api.github.com/repos/${USER_NAME}/${REPO_NAME}/git/refs/heads/${BRANCH_NAME} flutter_version.json
  22. RUN git clone https://github.com/${USER_NAME}/${REPO_NAME}.git -b ${BRANCH_NAME}
  23. # 现在设置 Flutter 路径,并构建 Flutter 工具并预缓存所有必要的工具,这很好
  24. # 因为只要 ADD 不使这些阶段无效,我们就不必重建这个昂贵的部分
  25. ENV PATH="$PATH:/flutter/bin"
  26. RUN flutter precache
  27. # 复制 Flutter 项目并切换到它
  28. COPY . ${WORKDIR}
  29. WORKDIR ${WORKDIR}
  30. # 运行 flutter clean、pub get 然后构建 Web 版本
  31. RUN flutter clean
  32. RUN flutter pub get
  33. RUN flutter build web
  34. # 服务于 Flutter Web 应用程序
  35. #
  36. # 在第二个阶段中,只需从第一个阶段复制构建的 Web 文件
  37. # 并将其作为静态网站使用基本的 Nginx 容器提供
  38. FROM nginx:latest
  39. # 设置工作目录
  40. ARG WORKDIR
  41. # 告诉使用哪个端口(不一定需要)
  42. EXPOSE 80
  43. # 将构建的 Flutter 静态网站复制到 Nginx 目录
  44. COPY --from=FLUTTER_BUILDER ${WORKDIR}/build/web /usr/share/nginx/html
英文:

I just had to add an increased timeout to the http requests inside the docker container. Seems like sometimes the Google CDN servers needs some time to respond or the corporate network blocks them completely.

I did this by adding ENV HTTP_TIMEOUT=5000 in the Dockerfile somewhere before the RUN flutter precache.

When it's still failing I just had to use a VPN to get out of the corporate network and it worked again.

With that change the Flutter build environment inside of the docker container works perfectly as expected even for Mac M1 and M2 (M series in general I guess) and also for Linux ARM platforms. Therefore this can also be considered as a workaround for the cirrusci/flutter docker container which throws errors like:

  1. ===== CRASH =====
  2. si_signo=Segmentation fault(11), si_code=1, si_addr=0x7
  3. version=2.18.0 (stable) (Fri Aug 26 10:22:54 2022 +0000) on "linux_x64"
  4. pid=173, thread=217, isolate_group=main(0x400305f000), isolate=main(0x40030d6000)
  5. isolate_instructions=4001ece300, vm_instructions=4001ece300
  6. pc 0x0000ffffa600472b fp 0x00000040103d51f0 Unknown symbol
  7. ...
  8. ...
  9. ...
  10. pc 0x00000040020999af fp 0x00000040103d5c60 dart::MessageHandler::TaskCallback()+0x1df
  11. pc 0x00000040021bc868 fp 0x00000040103d5ce0 dart::ThreadPool::WorkerLoop(dart::ThreadPool::Worker*)+0x148
  12. pc 0x00000040021bccbd fp 0x00000040103d5d10 dart::ThreadPool::Worker::Main(unsigned long)+0x6d
  13. pc 0x000000400212f488 fp 0x00000040103d5dd0 /sdks/flutter/bin/cache/dart-sdk/bin/dart+0x212f488
  14. -- End of DumpStackTrace
  15. qemu: uncaught target signal 6 (Aborted) - core dumped
  16. Aborted

on most ARM architectures. As referenced in this stackoverflow post: https://stackoverflow.com/questions/73751274/flutter-pub-get-fails-in-docker

The finally used Dockerfile to serve a flutter web app compiled and served from docker looks like this (don't forget to add CORS headers to your backend API server when serving the API from a different server or even port - these must be included especially in the preflight responses!):

  1. # setting workdir globally (still needs to be referenced in each stage!)
  2. ARG WORKDIR=/app
  3. # build the flutter web app
  4. #
  5. # in the first stage just prepare a ubuntu container
  6. # and install the flutter tooling to build flutter apps
  7. FROM ubuntu:latest AS FLUTTER_BUILDER
  8. # setting the workdir
  9. ARG WORKDIR
  10. # setting the github repo information from
  11. # which the flutter sdk will be cloned.
  12. ARG USER_NAME=flutter
  13. ARG REPO_NAME=flutter
  14. ARG BRANCH_NAME=stable
  15. # preparing the ubuntu container with all necessary tools
  16. RUN apt update -y
  17. RUN apt install -y bash curl file git unzip zip xz-utils libglu1-mesa
  18. # sometimes the Google servers respond a little slowly
  19. # which resulted in a failed handshake
  20. # increasing the timeout solves this error!
  21. ENV HTTP_TIMEOUT=5000
  22. # here we use ADD to invalidad cache of the docker stages below when there is a new commit/version in the
  23. # given flutter github repo on the given branch - watch out: depending on github api here!
  24. ADD https://api.github.com/repos/${USER_NAME}/${REPO_NAME}/git/refs/heads/${BRANCH_NAME} flutter_version.json
  25. RUN git clone https://github.com/${USER_NAME}/${REPO_NAME}.git -b ${BRANCH_NAME}
  26. # now set the path to flutter and build flutter tool and precache all necessary tools this is good
  27. # because as long as ADD doesn't invalidad these stages we don't have to rebuild this expensive part
  28. ENV PATH="$PATH:/flutter/bin"
  29. RUN flutter precache
  30. # copy the flutter project and change dir into it
  31. COPY . ${WORKDIR}
  32. WORKDIR ${WORKDIR}
  33. # run flutter clean, pub get and then build for web
  34. RUN flutter clean
  35. RUN flutter pub get
  36. RUN flutter build web
  37. # Serve the flutter web app
  38. #
  39. # in the second stage just copy the builded web files from the first
  40. # stage and serve them as static website using basic nginx container
  41. FROM nginx:latest
  42. # setting the workdir
  43. ARG WORKDIR
  44. # tell which port to use (no necessarily needed)
  45. EXPOSE 80
  46. # copy the built flutter static website to the nignx directory
  47. COPY --from=FLUTTER_BUILDER ${WORKDIR}/build/web /usr/share/nginx/html

huangapple
  • 本文由 发表于 2023年3月7日 19:42:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75661539.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定