Docker 加持的安卓手机:随身携带的知识库(一)

2024-05-04 08:04

本文主要是介绍Docker 加持的安卓手机:随身携带的知识库(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这篇文章聊聊,如何借助 Docker ,尝试将一台五年前的手机,构建成一个随身携带的、本地化的知识库。

写在前面

本篇文章,我使用了一台去年从二手平台购入的五年前的手机,K20 Pro。

用于实验的设备:K20 Pro

为了让它能够稳定持续的运行,我还为它准备了一个“加强版”的散热壳。

加强的“散热装备”

设想中的平时使用场景也非常简单,不需要插卡、不需要联网,一根 Type-C 数据线把它和电脑连在一起,就可以通过“本地连接”来访问手机中运行的提供服务的软件。

因为手机本身自带“UPS”(电池),所以即使突然断电,也不会出现数据的丢失,除此之外,因为手机已经是五年前的规格了,即使大手笔的购入顶配中的至尊版,成本也并不高,但是却可以比较轻松的获得一台 8核心、12GB 内存、500GB 的硬盘设备。甚至还有一块可以用来调试或者展示内容的“全面屏”,没有任何摄像头打孔的完整玻璃屏幕。

至于性能,如果能够完全配置正常,应该是非常有性价比,但是这应该需要一些折腾,所以本篇文章是第一篇,先验证可行性。

本文中的许多资料来自开源项目 CGCL-codes/Android-Container,感谢作者的辛苦劳动。不过项目距今为止已有三年没有更新,我个人推荐只做验证使用,一如本文中的使用方案。

为什么选择这台 K20 Pro

翻阅之前的文章,我发现我差不多每年都会折腾一下小米的手机。

  • 今年早些时候,聊过使用搭载 8Gen3 的红米 K70 Pro 跑模型《使用搭载骁龙 8 Gen 3 的安卓手机运行 AI 大模型》
  • 2023 年的时候,折腾过闲置的小米 12 Pro《小米 12 PRO 刷 MIUI 14 海外版(Android 12)》
  • 2022 年的时候,折腾过红米 11T Pro 《红米 11T PRO 刷机 MIUI 13 海外版》
  • 2021 年的时候,折腾过 K30 Pro《小米 K30 PRO 刷机 MIUI 12.5 海外版》
  • 2019 年的时候,折腾过 K20 Pro《小米 K20Pro 体验 Android 10》

因为种种原因,目前的小米开发者生态没有了过去的开放,开发者难以获取 Bootloader 权限,各种有趣的功能要排队内测,甚至 GitHub 上都出现了一些离谱的项目,比如 “小米高考题库”,来解决解锁刷机权限必须度过的大量八股测试题;“小米解锁项目”,“小米解锁方案合集” 等等项目。

**虽然,看起来现在的小米手机型号已经不再适合折腾。**但是,过去的手机,有没有可能变成一台比较有趣的设备,做一些比较有趣的事情呢?

毕竟,过去的小米手机还是很顶的!“守门员”、“焊门员”、“小金刚”这些产品形容词不光包含了营销成分,也有来自粉丝们的赞许。

准备工作

这次的准备工作非常简单,首先是“适合折腾的手机”,我选择的是 K20 Pro,你可以选择你喜欢的设备。

然后,是一台协助手机重获新生的“电脑”,Windows 或者 macOS 桌面系统的设备会比较方便,我使用的是 macOS。

最后,需要一根 Type-C 口的数据线,能够将手机连到电脑上。

第一步:解锁手机 Bootloader 权限

你可以参考上文中,我分享的之前的相关手机折腾记录,来将手机解锁,以便我们能够刷入 TWRP,并在后续过程中刷入验证 Docker 使用的新的安卓系统镜像。

如果你使用的设备也是 K20 Pro(Mi 9T Pro),可以从这里下载该设备的 TWRP 引导镜像。

更新设备的 BootLoader 非常简单,只需要电脑侧执行下面两条命令即可:

fastboot flash recovery twrp.img
fastboot reboot

第二步:按顺序刷入设备使用的系统镜像

在项目子目录文档的底部,我们能够找到用于验证的安卓镜像。

我们需要先刷入来自小米官方的 miui_RAPHAEL_V12.0.5.0.QFKCNXM_d03168fb55_10.0.zip 镜像,这个镜像发布自 2020 年 10 月 18 日,基于 Android 10 构建。如果项目页面下载比较慢,你可以从这里下载官方镜像。

在刷入官方镜像后,我们就可以刷入项目作者构建好的镜像 PixelExperience_raphael-10.0-20201204-0354-UNOFFICIAL-48bit-docker-criu.zip,来进行功能验证了。

在这个文档的上面,作者简单解释了如何进行镜像构建,而在另外一个目录中文档,则包含了另外一些比较重要的信息,包括如何给镜像内核做调整,来让 Docker 能够运行起来。

当我们完成镜像的更新后,就需要手动来完善运行环境,让 Docker 运行起来啦。

第三步:修复 Docker 运行环境

首先在一个命令行终端中执行:

adb shell

在进入一个交互式终端后,输入下面的命令,让我们能够修改系统中的只读目录:

mount -o rw,remount /

接着,我们将项目 Docker 目录和项目 files 目录的 files/dockerd.sh 使用 adb push 命令,传送到手机的 /system/bin/ 目录下,一个基本的 Docker 运行环境就就绪啦。

# adb push ./dockerd.sh /system/bin/dockerd.sh./dockerd.sh: 1 file pushed, 0 skipped. 7.7 MB/s (4016 bytes in 0.000s)...

为了我们操作 Docker 程序更方便,我们可以手动修复 docker-compose 命令,在 Compose 项目的发布页面,我们找到最新版本的 docker-compose-linux-aarch64 文件,下载,并使用上面的方式传送到手机环境中,并设置正确的执行权限。

# adb push ./docker-compose-linux-aarch64 /system/bin/docker-compose./docker-compose-linux-aarch64: 1 file pushed, 0 skipped. 32.2 MB/s (61276577 bytes in 1.815s)adb shell su -c "chmod +x /system/bin/docker-compose"

改进的 dockerd.sh

我对原始项目的 dockerd.sh 做了一些简单调整:

#!/system/bin/shmount -o rw,remount /# 创建 Docker 相关的目录
root_dirs=("/var" "/run" "/tmp" "/opt" "/usr" "/system/etc/docker")
for dir in "${root_dirs[@]}"; doif [ ! -d "$dir" ]; thenmkdir "$dir"fi
done# 创建 /data 目录相关的目录
data_dirs=("/data/var:/var" "/data/run:/run" "/data/tmp:/tmp" "/data/opt:/opt" "/data/etc/docker:/etc/docker")
for dir in "${data_dirs[@]}"; do# 分割目录路径和挂载点paths=$(echo "$dir" | tr ':' ' ')data_dir=$(echo "$paths" | cut -d ' ' -f 1)mount_dir=$(echo "$paths" | cut -d ' ' -f 2)# 如果 /data/var 目录存在,清理目录中的 ./run 目录if [ "$data_dir" = "/data/var" ] && [ -d "$data_dir" ]; thenrm -rf /data/var/runfi# 尝试创建并挂载目录mkdir -p "$data_dir"mount --bind "$data_dir" "$mount_dir"echo "mount $data_dir to $mount_dir"
done# 创建 /dev 目录相关的目录,并挂载 cgroup
cgroup_dirs=("cpu" "cpuacct" "devices" "freezer" "hugetlb" "net_cls" "net_prio" "perf_event" "pids" "rdma")
for dir in "${cgroup_dirs[@]}"; doif [ ! -d "/dev/$dir" ]; thenmkdir -p "/dev/$dir"case "$dir" in"cpu"|"cpuacct");;*)echo "mount -t cgroup -o $dir none /dev/$dir"mount -t cgroup -o $dir none /dev/$dir;;esacfi
done# 为 Docker 添加路由表
ip_rule1=$(ip rule | grep "from all lookup main" | wc -l)
if [ "$ip_rule1" -ne 1 ]; thenip rule add pref 1 from all lookup main
fi
ip_rule2=$(ip rule | grep "from all lookup default" | wc -l)
if [ "$ip_rule2" -ne 1 ]; thenip rule add pref 2 from all lookup default
fi# 设置 Docker 镜像加速
echo "{\"registry-mirrors\":[\"https://mirror.baidubce.com\"],\"experimental\":true}" > /etc/docker/daemon.json
# 关闭默认防火墙,允许外部访问 Docker 容器端口
setenforce 0
# 启动 Docker
export DOCKER_RAMDISK=true
dockerd --add-runtime crun=/bin/crun -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock > /dev/null 2>&1 &

搭配注释,做了什么应该都非常清楚啦,这里就不展开赘述了。等到重新构建镜像的时候,我们再进行进一步的优化(内置 & 精简)。

第四步:启动 Docker 后台进程

当我们将所有文件都传输到手机上之后,在 adb shell 环境中把 docker 进行拉起来,Docker 运行环境就准备就绪啦。

# dockerd.sh                                                                                                                                                                       mount /data/var to /var
mount /data/run to /run
mount /data/tmp to /tmp
mount /data/opt to /opt
mount /data/etc/docker to /etc/docker
mount -t cgroup -o devices none /dev/devices
mount -t cgroup -o freezer none /dev/freezer
mount -t cgroup -o hugetlb none /dev/hugetlb
mount -t cgroup -o net_cls none /dev/net_cls
mount -t cgroup -o net_prio none /dev/net_prio
mount -t cgroup -o perf_event none /dev/perf_event
mount -t cgroup -o pids none /dev/pids
mount -t cgroup -o rdma none /dev/rdma

这个时候,执行 docker info 就能够看到 docker 的基础运行环境状况啦:

# docker infoClient:Debug Mode: falseServer:Containers: 1Running: 1Paused: 0Stopped: 0Images: 7Server Version: 19.03.13Storage Driver: overlay2Backing Filesystem: extfsSupports d_type: trueNative Overlay Diff: falseLogging Driver: json-fileCgroup Driver: cgroupfsPlugins:Volume: localNetwork: bridge host ipvlan macvlan null overlayLog: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslogSwarm: inactiveRuntimes: runc crunDefault Runtime: runcInit Binary: docker-initcontainerd version: 8fba4e9a7d01810a393d5d25a3621dc101981175runc version: dc9208a3303feef5b3839f4323d9beb36df0a9ddinit version: fec3683Security Options:seccompProfile: defaultKernel Version: 4.14.180-F1xy-0.19-pe-ten/71771c10beOSType: linuxArchitecture: aarch64CPUs: 8Total Memory: 11.25GiBName: localhostID: LLQY:OOXR:BKTQ:M2ZP:MGUJ:Q3NY:RPZL:EV7D:YGQY:H45D:BKUY:RXMADocker Root Dir: /var/lib/dockerDebug Mode: falseRegistry: https://index.docker.io/v1/Labels:Experimental: trueInsecure Registries:127.0.0.0/8Registry Mirrors:https://mirror.baidubce.com/Live Restore Enabled: falseProduct License: Community EngineWARNING: API is accessible on http://0.0.0.0:2375 without encryption.Access to the remote API is equivalent to root access on the host. Referto the 'Docker daemon attack surface' section in the documentation formore information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface

第五步:创建一个 Docker 应用

Docker 环境就绪后,我们来测试 Docker 应用能否运行。先创建一个目录,用于后续存放 Docker 应用数据:

mkdir -p kb
cd kb

随后,在目录中创建一个内容如下的 docker-compose.yml 配置文件:

version: '3'services:wordpress:image: soulteary/sqlite-wordpress:6.5.2restart: alwaysports:- 8080:80volumes:- ./wordpress:/var/www/html

没错,这个配置来自项目 soulteary/docker-sqlite-wordpress,在之前的文章《WordPress 告别 MySQL:Docker SQLite WordPress》、《WordPress SQLite Docker 镜像封装细节》中,讲的比较详尽了,就不在此展开啦。

当我们准备好 docker-compose.yml 后,执行 docker-compose up -d

# docker-compose up -d
WARN[0000] /kb/docker-compose.yml: `version` is obsolete 
[+] Running 1/0✔ Container kb-wordpress-1  Running 

WordPress 就很快的通过容器的方式启动起来啦。

启动应用后,我们使用下面的命令,可以简单验证服务是否正常运行:

docker exec kb-wordpress-1 curl -L http://0.0.0.0:80

不出意外,我们将得到类似下面的结果:

使用命令行验证手机上的 Docker 应用

上面的图片中,我们使用命令行来验证了 WordPress 中的程序渲染出了 HTML 页面,虽然执行时间非常长(需要排查或重新构建 Android 验证),但是证明了 Android 上运行 Docker 程序是可行的。

第六步:如何在电脑侧访问手机的应用

Android Debug Bridge(ADB)中有一个很有用的命令叫做 forward,我们可以通过这个命令,将电脑上的端口和手机上应用的端口进行打通。

 forward --list           list all forward socket connectionsforward [--no-rebind] LOCAL REMOTEforward socket connection using:tcp:<port> (<local> may be "tcp:0" to pick any open port)localabstract:<unix domain socket name>localreserved:<unix domain socket name>localfilesystem:<unix domain socket name>dev:<character device name>jdwp:<process pid> (remote only)vsock:<CID>:<port> (remote only)acceptfd:<fd> (listen only)forward --remove LOCAL   remove specific forward socket connectionforward --remove-all     remove all forward socket connections

命令支持四种参数调用方法,分别是:

  • 以列表形式获取所有的转发映射
  • 进行本地和远程端口的转发映射
  • 撤销一个本地端口的转发映射
  • 撤销所有的转发映射

我们以实际的情况举例,上文中,我们在手机上将 WordPress 默认运行的 80 端口,映射到了手机的 8080 端口。如果我们将电脑的 8088 端口和手机上的 8080 端口打通,那么我们需要执行下面的命令:

adb forward tcp:8088 tcp:8080

当命令执行完毕后,我们就可以在浏览器中访问 http://localhost:8088 来访问手机上的应用啦。

使用电脑直接访问手机容器应用

当然,这里也会遇到和上面一样的问题,访问应用的时间会比较长。这是一个需要继续排查和解决的问题。毕竟除了 PHP 程序执行外的资源路径的响应都在 ms 级别。

当然,如果你希望这台设备上运行的 Docker 程序,能够在局域网共享,只需要让手机连上 Wi-Fi,然后在浏览器中访问手机在局域网中的 IP 地址,和对应的程序端口即可。

使用局域网访问手机上的容器应用

是不是十分简单,如果你想离线本地化使用,就不需要给手机网络,如果你想局域网共享,得到一台低成本、高性价比的 Linux 服务器,就让它连上 Wi-Fi。

最后

写到这里,本文提到的验证目标就结束啦。接下来相关的文章里,我们来聊聊本文遇到的性能问题,以及如何在 2024 年更简单的构建支持 Docker 运行的安卓内核和镜像。

我们下篇文章再见。

–EOF


我们有一个小小的折腾群,里面聚集了一些喜欢折腾、彼此坦诚相待的小伙伴。

我们在里面会一起聊聊软硬件、HomeLab、编程上、生活里以及职场中的一些问题,偶尔也在群里不定期的分享一些技术资料。

关于交友的标准,请参考下面的文章:

苏洋:致新朋友:为生活投票,不断寻找更好的朋友

当然,通过下面这篇文章添加好友时,请备注实名和公司或学校、注明来源和目的,珍惜彼此的时间 😄

苏洋:关于折腾群入群的那些事


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2024年05月03日
统计字数: 9721字
阅读时间: 20分钟阅读
本文链接: https://soulteary.com/2024/05/03/docker-powered-android-phone-knowledge-base-you-can-carry-with-you-1.html

这篇关于Docker 加持的安卓手机:随身携带的知识库(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/958725

相关文章

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

cell phone teardown 手机拆卸

tweezer 镊子 screwdriver 螺丝刀 opening tool 开口工具 repair 修理 battery 电池 rear panel 后盖 front and rear cameras 前后摄像头 volume button board 音量键线路板 headphone jack 耳机孔 a cracked screen 破裂屏 otherwise non-functiona

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“

禅道Docker安装包发布

禅道Docker安装包发布 大家好, 禅道Docker安装包发布。 一、下载地址 禅道开源版:   /dl/zentao/docker/docker_zentao.zip  备用下载地址:https://download.csdn.net/download/u013490585/16271485 数据库用户名: root,默认密码: 123456。运行时,可以设置 MYSQL_ROOT_P

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求,一定不要错过这个机会。赶紧去看看吧! 什么是华为云Flexus X实例 华为云Flexus X实例云服务是新一代开箱即用、体

docker-compose安装和简单使用

本文介绍docker-compose的安装和使用 新版docker已经默认安装了docker-compose 可以使用docker-compose -v 查看docker-compose版本 如果没有的话可以使用以下命令直接安装 sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-c

01 Docker概念和部署

目录 1.1 Docker 概述 1.1.1 Docker 的优势 1.1.2 镜像 1.1.3 容器 1.1.4 仓库 1.2 安装 Docker 1.2.1 配置和安装依赖环境 1.3镜像操作 1.3.1 搜索镜像 1.3.2 获取镜像 1.3.3 查看镜像 1.3.4 给镜像重命名 1.3.5 存储,载入镜像和删除镜像 1.4 Doecker容器操作 1.4

安卓玩机工具------小米工具箱扩展工具 小米机型功能拓展

小米工具箱扩展版                     小米工具箱扩展版 iO_Box_Mi_Ext是由@晨钟酱开发的一款适用于小米(MIUI)、多亲(2、2Pro)、多看(多看电纸书)的多功能工具箱。该工具所有功能均可以免root实现,使用前,请打开开发者选项中的“USB调试”  功能特点 【小米工具箱】 1:冻结MIUI全家桶,隐藏状态栏图标,修改下拉通知栏图块数量;冻结

Windows与linux中docker的安装与使用

windos中安装使用docker 下载Docker_Desktop 安装包进入docker官网下载Docker_Desktop: https://www.docker.com/ 启用wsl 我们搜索“启用或关闭Windows功能”,打开后勾选适用于Linux的Windows 子系统 Docker_Desktop设置 出现Docker Engine stopped的解决