H5W3
当前位置:H5W3 > 其他技术问题 > 正文

[译]如何 docker 化 flutter apps

原文

如今 app 开发不再完全是写代码的事了.多语言、多架构、及多环境使得 app 开发流程更加复杂且维护成本变高.

而 Dokcer 可以帮助简化、加速这一开发流程,针对每个项目提供选择工具和维护多种不同开发环境的自由.

本文将探索如何利用 Docker 简化 flutter app 的开发流程.

使用 Docker 的优势

使用 Docker 容器的优势有无数条,这里仅列举几条比较重要的:

  • 如果你升级了系统(或者使用朋友的电脑),为了编译 flutter app,你得手动下载所有的相关编译工具.而 docker 就可以跳过手动配置这个过程.只需要从你的 github 下载 Dockerfile 文件(保存了相关编译配置), 然后运行即可.编译、测试、调试 flutter app 只需要等待 Docker 容器下载完成并运行.
  • 彻底忘记它在我电脑上运行的好好的吧. Dokcer 容器使用了同一份 Dockerfile,在运行时所有的工具将完全一致,无论当前运行的是在哪个云服务平台或操作系统.
  • Docker 容器因为不需要有独立的操作系统所以非常轻量便携.相对于虚拟机来说,这种架构对资源的需求随依赖的负载而变,且启动快.
  • 易伸缩,且不需要在 docker 容器中安装操作系统.不像虚拟机需要申请永久资源.

docker 容器是什么

docker 容器镜像是一个轻量级、独立、包含运行应用一切所需(代码、运行时、系统工具、系统库及相关配置)的可执行软件包集合.当它运行在 docker 引擎上时就变成了一个 docker 容器.

查看 更多关于 docker 容器的知识和容器与虚拟机的区别

配置 docker

首先下载对应操作系统的 docker 引擎.

注意: 在 Windows 上使用 Docker 需要在 BIOS 开启硬件加速虚拟化技术.查看 StackOverflow 上的相关讨论.

安装完后先确认 docker 是否可以正常运行(macOS 和 linux 使用终端, Windows 使用 PowerShell).

docker --version
 

然后会显示当前操作系统安装的 docker 版本号

Docker version 19.03.8, build afacb8b
 

可以通过下面命令测试 docker(会从 DokcerHub 下载 hello-world 镜像)

docker run hello-world
 

如果是第一次运行会显示如下结果

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
ca4f61b1923c: Pull complete
Digest: sha256:ca0eeb6fb05351dfc8759c20733c91def84cb8007aa89a5bf606bc8b315b9fc7
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
 

如果是 linux 用户,为了在 VS Code 环境中使用需要给予 root 权限.创建 docker 组添加用户.

如下所示:

1、创建 docker 组

sudo groupadd docker
 

2、向 docker 组添加用户

sudo usermod -aG docker $USER
 

3、linux 环境下,运行如下命令激活组

newgrp docker
 

4、验证是否无 sudo 可以运行 docker 命令

docker run hello-world
 

linux 安装后操作查看官方指南

配置 VS Code

接下来将从 VS Code 环境中访问 docker 容器,这样就可在 VS Code 中直接访问 flutter 目录.这将简化 flutter 开发流程

  • 下载 VS Code
  • 下载并安装两个 VS Code 插件
    • docker
    • Remote Development

创建 docker 容器

1、创建 flutter_docker 目录

mkdir flutter_docker
 

2、 使用 VS Code 打开此目录

code flutter_docker
 

3、新建 Dockerfile 文件
4、向 Dockerfile 添加如下内容

FROM ubuntu:18.04
# 前置要求
RUN apt update && apt install -y curl git unzip xz-utils zip libglu1-mesa openjdk-8-jdk wget

# 设置新用户
RUN useradd -ms /bin/bash developer
USER developer
WORKDIR /home/developer

# 准备安卓目录和系统变量
RUN mkdir -p Android/sdk
ENV ANDROID_SDK_ROOT /home/developer/Android/sdk
RUN mkdir -p .android && touch .android/repositories.cfg

# 设置安卓 SDK
RUN get -O sdk-tools.zip https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
RUN unzip sdk-tools.zip && rm sdk-tools.zip
RUN mv tools Android/sdk/tools
RUN cd Android/sdk/tools/bin && yes | ./sdkmanager --lincenses
RUN cd Android/sdk/tools/bin && ./sdkmanager "build-tools;29.0.2" "sources;android-29"
ENV PATH "$PATH:/home/deveoper/Android/sdk/platform-tools"
# 下载 flutter SDK
RUN git clone https://github.com/flutter/flutter.git
ENV PATH "$PATH:/home/developer/flutter/bin"
# 检测 flutter
RUN flutter doctor
 

5、创建 .devcontainer 文件夹,并在其中新建 devcontainer.json文件
6、为 devcontainer.json 添加如下内容:

{
"name": "flutter_docker",
"context": ".",
"dockerFile": "../Dockerfile",
"remoteUser": "developer",
"mounts": [
"source=/dev/bus/usb,target=/dev/bus/usb,type=bind"
],
"settings": {
"terminal.integrated.shell.linux": null
},
"runArgs": ["--privileged"],
"extensions": ["dart-core.flutter"],
"workspaceMount": "source=${localWorkspaceFolder}/workspace,target=/home/developer/workspace,type=bind,consistency=delegated",
"workspaceFolder":"/home/developer/workspace"
}
 

重要提醒: macOS 和 Windows 的用户无法通过 mounts 属性访问 USB 端口.不要在 devcontainer.json 中定义这个属性,否则会导致 docker 容器构建失败.更多内容后面会介绍.

7、在根目录下添加 workspace 文件夹.此文件夹将用来存储 flutter 项目在 docker 容器内部创建的内容.

现在就可以在 VS Code 环境中构建运行容器.在这之前,先来了解下 Dockerfiledevcontainer.json.

当然可以使用官方团队维护的 flutter docker 镜像, 比如cirrusci/flutter

了解 Dockerfile

Dockerfile 是一个包含了用户在命令行打包镜像时用到的命令的文本文件.docker 可以通过读取 Dockerfile 文件指令自动构建镜像.

这个构建过程是由 Docker 守护进程实现的,不是 CLI.

我们定义的 Dokcerfile 将下载和安装开发 flutter apps 需要的所有必要工具.

1、FROM: 从ubuntu:18.04 docker 镜像中创建新的层.
2、在使用RUN命令之前,所有必要的包都是通过apt下载安装的.

  • curl git unzip xz-utils zip libglu2-mesa flutter SDK 依赖
  • openjdk-8-jdk Android SDK 依赖
  • wget 用来下载某些 Android tools
    3、添加非 root 用户 developer,设为当前用户,改变当前工作文件夹到 home 目录下
RUN useradd -ms /bin/bash developer
USER developer
WORKDIR /home/developer
 

4、创建 Android SDK 安装目录.设置 ANDROID_SDK_ROOT 环境变量, flutter 会用到

RUN mkdir -p Android/sdk
ENV ANDROID_SDK_ROOT /home/developer/Android/sdk
RUN mkdir -p .android && touch .android/repositories.cfg
 

5、下载最新的 SDK 工具.解压然后移动到正确的文件夹下.然后使用 sdkmanager接受 Android License 并下载.最后添加 adb 路径.

此处我特别指定了 API29,如果想使用其他 Android 版本,也可以指定其他.

RUN wget -O sdk-tools.zip https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
RUN unzip sdk-tools.zip && rm sdk-tools.zip
RUN mv tools Android/sdk/tools
RUN cd Android/sdk/tools/bin && yes | ./sdkmanager --licenses
RUN cd Android/sdk/tools/bin && ./sdkmanager "build-tools;29.0.2" "patcher;v4" "platform-tools" "platforms;android-29" "sources;android-29"
ENV PATH "$PATH:/home/developer/Android/sdk/platform-tools"
 

6、从 github 仓库克隆 Flutter, 为 flutter 命令添加 PATH 环境变量.

RUN git clone https://github.com/flutter/flutter.git
ENV PATH "$PATH:/home/developer/flutter/bin"
 

7、最后运行flutter doctor 命令下载 Dart SDK 来检查 flutter 是否配置正确.

RUN flutter doctor
 

了解 devcontainer.json

devcontainer.json 告诉 VS Code 如何访问(或创建)一个定义好的工具和运行时栈的开发环境.

访问这里获取更多信息

我们在 devcontainer.json 中使用到的属性如下所述:

  • name: 容器的名称
  • context: docker 相对于 devcontainer.json 文件构建的工作目录.
  • dockerFile: Dockerfile 的位置,相对于 devcontainer.json 文件来说.
  • remoteUser: 将在容器中使用的用户名
  • mounts: 在容器运行时被添加到的挂载点数组.此处我们把/dev/bus/usb挂载,以便容器能探测到任何安卓设备链接到系统(macOS 和 Windows 不可用)
  • settings: 向容器/机器指定的设置文件添加 settings.json 值.
  • runArgs: 有效的 docker 参数,string 数组. 使用 --privigleged 可以确保容器能访问链接到系统的设备.
  • extensions: 指定当容器创建时应该安装的扩展 ID 数组.dart-code.flutter是 flutter 开发的官方扩展。
  • workspaceMount: 覆盖本地默认的挂载工作空间
  • workspaceFolder: 当链接到容器时 VS Code 应该打开的默认路径.

更多 devcontianer.json属性查看这里

构建运行 docker 容器

如果已经为 VS Code 安装过 Remote Development 插件, 那么在 VS Code 窗口的左下角会看到显示的图标.

1、点击此图标
2、选择弹出来的选项: Remote-Containers: Open Folder in Container
3、选择包含 Dockerfile(还有其他设置) 容器的根目录打开开始构建 docker 容器.这需要一点时间,因为它需要下载并为此容器配置所有工具.

构建完成后,将会自动打开 docker 容器的 bash 终端.

开始开发

首先运行 flutter doctor 验证所有配置是否正确.

可能会看到在 Android Studio 和 Connected device 旁边有黄色的警示.

Android Studio 的警示是因为我们未安装 flutter 和 dart 插件.因为我们用 VS Code 开发,所以可以忽略.

Connected device 警示是因为我们没有连接设备.

重要提示: 下面的步骤仅适用于用户可以通过 USB 端口访问安卓设备的 Linux 操作系统.如果是 macOS 或 Windows,那么可以跳过.

现在通过 USB 端口连接安卓设备.

在手机上设置 PTP文件传输 连接模式.

接下来再运行就不会看到黄色警示了.

如果没有看到绿色对号,那么可能是当前系统 adb 的问题, adb 一定得连接上.运行在手机上的 ADB 守护进程是无法同时连接两个 ADB server的.所以在当前系统运行如下命令断开 ADB 连接
adb kill-server
现在应该可以通过 docker 里的 adb 连接上设备了.

使用 flutter create demo 创建 flutter 项目.

在 workspace 目录下将会创建 demo 项目.

进入此目录然后运行

cd demo
flutter run
 

此时就会从 docker 容器中直接在连接的手机运行 flutter app.

macOS 和 Windows 开发者

macOS 和 Windows 开发者无法在 docker 容器通过 USB 端口访问手机.所以只有通过 TCP/IP 和手机建立无线连接才能访问.

首先得在操作系统安装 adb.adb 在 Android SDK platform-tools 目录下,记得设置 PATH 变量,然后连接手机,开启调试模式.

1、列出当前连接的设备

adb devices
 

2、开启无线连接

adb tcpip 555
adb connect 192.168.0.5:5555
adb devices
 

此处把 IP 地址替换为连接手机的 wifi 地址.
注意: 手机和电脑得处在同一局域网下.

3、断开手机的 USB 连接,然后再运行 adb devices 验证此设备是否仍然连接.

4、在 VS Code 运行 docker 容器
5、在容器里的终端运行 adb devices 验证设备是否可访问.
此时会返回空列表
6、执行如下命令

adb connect 192.168.0.5:5555
adb devices
 

此处的 IP 和端口应和链接到电脑的一致.
同时确保打开手机弹出的允许 USB 调试 窗口

7、如果出现 unauthorized,那么按如下操作

adb kill-server
adb connect 192.168.0.5:5555
adb devices
 

这样 unauthorized 就会消失了.

8、flutter doctor

结论

docker 可以帮助简化 flutter 应用开发流程,保证开发过程一致。

github

本文地址:H5W3 » [译]如何 docker 化 flutter apps

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址