id: 7e0d2e7c884c444bb3690ae62455cf2d
parent_id: 
item_type: 1
item_id: 5ff80ac324bc44eca6ed6a1d429163a4
item_updated_time: 1764345603112
title_diff: "[{\"diffs\":[[1,\"Docker容器搭建android编译环境-今日头条\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":26}]"
body_diff: "[{\"diffs\":[[1,\"<html>\\\r\\\n<head>\\\r\\\n  <title>Docker容器搭建android编译环境-今日头条</title>\\\r\\\n  <basefont face=\\\"微软雅黑\\\" size=\\\"2\\\" />\\\r\\\n  <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html;charset=utf-8\\\" />\\\r\\\n  <meta name=\\\"exporter-version\\\" content=\\\"YXBJ Windows/608924 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;\\\"/>\\\r\\\n  <style>\\\r\\\n\\tbody, td {\\\r\\\n\\t  font-family: 微软雅黑;\\\r\\\n\\t  font-size: 12pt;\\\r\\\n\\t}\\\r\\\n  </style>\\\r\\\n</head>\\\r\\\n<body>\\\r\\\n<a name=\\\"26502\\\"></a>\\\r\\\n<h1>Docker容器搭建android编译环境-今日头条</h1>\\\r\\\n\\\r\\\n<div><span style=\\\"margin:0px;\\\"><div><div style=\\\"font-size: 18px; font-family: PingFangSC-Regular; letter-spacing: 1.2px; line-height: 30px; text-align: justify;\\\"><div style=\\\"\\\"><div><h1>部署容器</h1><h1>1.1 手动部署</h1><h1>1.1.1 配置docker</h1><pre><code># 安装之前必须修改docker路径，防止docker空间增长暴满。sudo ln -s /opt/docker /<span style=\\\"\\\">var</span>/lib/docker# 安装docker.iosudo apt-<span style=\\\"\\\">get</span> install docker.io# 设置docker命令免rootsudo usermod -aG docker ${whoami}sudo shutdown -r now</code></pre><h1>1.1.2 启动容器</h1><pre><code><span style=\\\"\\\">#</span><span style=\\\"\\\"> 启动容器ubuntu18.04。android编译环境不宜超过ubuntu18版本，否则问题多多。</span></code></pre><h1>1.1.3 配置环境</h1><p style=\\\"\\\">进入容器之后，我们就可以安装AOSP的编译环境。不同的AOSP版本安装库可能会有差异，具体可以参考AOSP官网。这里以Android7.1为例。</p><p style=\\\"\\\">可以直接将这个脚本放在宿主机的/opt/aosp中，在容器内直接执行：</p><pre><code>#!<span style=\\\"\\\">/bin/</span>bash# 切换容器内apt源mv /etc/apt/sources.list /etc/apt/sources.list.rawecho -e <span style=\\\"\\\">&quot;deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>apt/sources.listapt-<span style=\\\"\\\">get</span> update# 安装编译库。需要根据不同的linux系统版本和android版本来配置。详情参看官网。apt-<span style=\\\"\\\">get</span> install -y -qq --no-install-recommends sudoers vim ssh telnet git repo openjdk<span style=\\\"\\\">-8</span>-jdkapt-<span style=\\\"\\\">get</span> install -y -qq --no-install-recommends zip unzip flex bc bison rsync gperf gnupg m4 ccache curl genisoimage xsltproc tofrodosapt-<span style=\\\"\\\">get</span> install -y -qq --no-install-recommends build-essential gcc-multilib g++-multilibapt-<span style=\\\"\\\">get</span> install -y -qq --no-install-recommends libc6-dev-i386 lib32z-dev lib32ncurses5-devapt-<span style=\\\"\\\">get</span> install -y -qq --no-install-recommends dpkg-dev x11proto-core-dev zlib1g-devapt-<span style=\\\"\\\">get</span> install -y -qq --no-install-recommends libsdl1<span style=\\\"\\\">.2</span>-dev libx11-dev libgl1-mesa-dev libgl1-mesa-dev libxml2-utils libssl-dev# 清除安装缓存，减少容器大小。apt-<span style=\\\"\\\">get</span> cleanrm -rf /<span style=\\\"\\\">var</span>/lib/apt/lists</code></pre><h1>1.2 Dockerfile</h1><p style=\\\"\\\">这里有一个参考脚本，根据android官网提供的脚本修改。</p><pre><code>FROM ubuntu:<span style=\\\"\\\">18.04</span># 根据官网提供的需要安装的编译库RUN apt-<span style=\\\"\\\">get</span> update \\\\ &amp;&amp; apt-<span style=\\\"\\\">get</span> install -y -qq --no-install-recommends zip unzip flex bc rsync bison gperf gnupg m4 ccache curl genisoimage xsltproc tofrodos \\\\ build-essential gcc-multilib g++-multilib libc6-dev-i386 lib32z-dev lib32ncurses5-dev kmod dpkg-dev x11proto-core-dev zlib1g-dev \\\\ libsdl1<span style=\\\"\\\">.2</span>-dev libx11-dev libgl1-mesa-dev libgl1-mesa-dev libxml2-utils libssl-dev# 设置几个环境变量# 一定要设置USER这个变量，不然AOSP的soong编译报错RUN apt-<span style=\\\"\\\">get</span> install -y -qq --no-install-recommends vim git repo openjdk<span style=\\\"\\\">-8</span>-jdk \\\\ &amp;&amp; echo <span style=\\\"\\\">&quot;# ++++++++++++++++++++++++++++++++++++++++&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>profile \\\\ &amp;&amp; echo <span style=\\\"\\\">&quot;export USER=root&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>profile \\\\ &amp;&amp; echo <span style=\\\"\\\">&quot;export REPO_URL=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>profile \\\\ &amp;&amp; echo <span style=\\\"\\\">&quot;export HEXAGON_ROOT=/opt/sdkits/qcom/hexagon&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>profile \\\\ &amp;&amp; echo <span style=\\\"\\\">&quot;# JAVA PATH&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>profile \\\\ &amp;&amp; echo <span style=\\\"\\\">&quot;export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>profile \\\\ &amp;&amp; echo <span style=\\\"\\\">&quot;export JRE_HOME=\\\\${JAVA_HOME}/jre&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>profile \\\\ &amp;&amp; echo <span style=\\\"\\\">&quot;export CLASSPATH=\\\\${JAVA_HOME}/lib:\\\\${JRE_HOME}/lib&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>profile \\\\ &amp;&amp; echo <span style=\\\"\\\">&quot;export PATH=\\\\${PATH}:\\\\${JAVA_HOME}/bin&quot;</span> &gt;&gt; <span style=\\\"\\\">/etc/</span>profile# 设置root默认密码，配置ssh-serverRUN apt-<span style=\\\"\\\">get</span> install openssh-server \\\\ &amp;&amp; echo <span style=\\\"\\\">'root:root1234'</span> | chpasswd \\\\ &amp;&amp; sed -i <span style=\\\"\\\">'s/UsePAM yes/UsePAM no/g'</span> /etc/ssh/sshd_config \\\\ &amp;&amp; sed -i <span style=\\\"\\\">'s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g'</span> /etc/ssh/sshd_configEXPOSE <span style=\\\"\\\">22</span>VOLUME [<span style=\\\"\\\">&quot;/opt/externs&quot;</span>, <span style=\\\"\\\">&quot;/opt/sdkits&quot;</span>]# 入口函数。用户自定。ENTRYPOINT [<span style=\\\"\\\">&quot;starts.sh&quot;</span>]</code></pre><p style=\\\"\\\">Dockerfile编译运行的时间太长了，我一般不用这个操作。</p><h1>2 镜像管理</h1><p style=\\\"\\\">我们需要将这个镜像提交成标准镜像，作为基础环境公用。</p><pre><code><span style=\\\"\\\">docker</span> commit -a <span style=\\\"\\\">&quot;newuser&quot;</span> -m <span style=\\\"\\\">&quot;aosp imange based on ubuntu18.04&quot;</span> &lt;CONTAINER_ID&gt; xxx/aosp:v1.<span style=\\\"\\\">0</span></code></pre><p style=\\\"\\\">如有必要，还需要导出镜像文件备用：</p><pre><code><span style=\\\"\\\">#</span><span style=\\\"\\\"></span></code></pre><h1>3 容器管理</h1><p style=\\\"\\\">在实际的团队开发管理中，我们需要考虑分配容器给团队成员使用。分配容器的方式有两种：</p><ol start=\\\"1\\\"><li>每个用户分配一个容器，容器通过端口号来区分。</li><li>所有用户共用一个基础容器，按照用户名来使用。</li></ol><p style=\\\"\\\">不建议使用IP地址的方式是因为需要固定容器IP地址，这在企业局域网内限制比较多，很多非技术层面的问题比较复杂。</p><h1>3.1 每个用户各用容器</h1><h1>3.1.1 服务端配置</h1><p style=\\\"\\\">每个用户需要配置一个独立的容器。每个容器以端口号（而不是以IP地址）来进行区分。</p><pre><code><span style=\\\"\\\">docker</span><span style=\\\"\\\">run</span><span style=\\\"\\\">-td</span><span style=\\\"\\\">--name</span><span style=\\\"\\\">YOURNAME</span><span style=\\\"\\\">-v</span> /<span style=\\\"\\\">opt</span>/<span style=\\\"\\\">dockerdirs</span>/<span style=\\\"\\\">YOURNAME</span>:/<span style=\\\"\\\">opt</span>/<span style=\\\"\\\">aosp</span><span style=\\\"\\\">-p</span><span style=\\\"\\\">2221</span><span style=\\\"\\\">:22</span><span style=\\\"\\\">xxx</span>/<span style=\\\"\\\">aospbase</span><span style=\\\"\\\">:v1</span><span style=\\\"\\\">bin</span>/<span style=\\\"\\\">bash</span></code></pre><blockquote><p style=\\\"\\\">需要配置的几个参数：</p>1、容器名称：--name YOURNAME，修改成：用户名称-镜像-id2、host挂载目录：/opt/dockerdirs/YOURNAME， 按照用户名归类，防止目录混乱。3、ssh端口：2201:22, 建议从2220 ~ 2299进行分配。<p></p></blockquote><h1>3.1.2 客户端使用</h1><p style=\\\"\\\">用户登陆容器：</p><pre><code><span style=\\\"\\\">ssh</span> -p <span style=\\\"\\\">2201</span> root@<span style=\\\"\\\">192.168.1.1</span></code></pre><blockquote><p style=\\\"\\\">默认用户： root</p>默认密码： root1234<p></p></blockquote><blockquote><p style=\\\"\\\">使用说明：</p>1、务必把资料信息保存在/opt/externs目录中，docker崩溃之后文件不会丢失。2、不要停止掉ssh服务，否则无法进入docker容器。3、容器默认没有UI界面和桌面程序。 如果需要安装UI界面和工具，请自己安装X11或者ubuntu-desktop。可以自己在容器内进行安装操作。4、不要把编译服务器用来存储文件备份等。容器一旦超过一定大小，就会被管理员清空删除。<p></p></blockquote><h1>3.2 多用户共用容器</h1><p style=\\\"\\\">多个用户共用同一个容器，容器就需要配置多用户。每个容器的root用户是不能提供给用户使用的。</p><h1>3.2.1 服务端配置</h1><pre><code># 给root设置密码，不让其他人访问。passwd root# adduser新增用户及密码<span style=\\\"\\\">1234</span>，并创建/home/user目录# useradd不会创建/home/user目录adduser newuserAdding user <span style=\\\"\\\">`newuser' ...Adding new group `</span>newuser<span style=\\\"\\\">' (1000) ...Adding new user `newuser'</span> (<span style=\\\"\\\">1000</span>) <span style=\\\"\\\">with</span> group <span style=\\\"\\\">`newuser' ...Creating home directory `</span>/home/newuser<span style=\\\"\\\">' ...Copying files from `/etc/skel'</span> ...Enter <span style=\\\"\\\">new</span> UNIX password: Retype <span style=\\\"\\\">new</span> UNIX password: passwd: password updated successfullyChanging the user information <span style=\\\"\\\">for</span> newuserEnter the <span style=\\\"\\\">new</span> value, or press ENTER <span style=\\\"\\\">for</span> the <span style=\\\"\\\">default</span> Full Name []: Room <span style=\\\"\\\">Number</span> []: Work Phone []: Home Phone []: Other []: Is the information correct? [Y/n]# 修改/etc/sudoers增加sudo权限newuser ALL=(ALL:ALL) ALL</code></pre><h1>3.2.2 客户端使用</h1><p style=\\\"\\\">用户登陆容器，使用的是公共端口，但是用户名各不相同：</p><pre><code><span style=\\\"\\\">ssh</span> -p <span style=\\\"\\\">2201</span> newuser@<span style=\\\"\\\">192.168.1.1</span></code></pre></div></div></div></div></span>\\\n</div></body></html>\\u0000\"]],\"start1\":0,\"start2\":0,\"length1\":0,\"length2\":9110}]"
metadata_diff: {"new":{"id":"5ff80ac324bc44eca6ed6a1d429163a4","parent_id":"f67288c3a0be4374b5d532b5dcc3aabc","latitude":"0.00000000","longitude":"0.00000000","altitude":"0.0000","author":"","source_url":"","is_todo":0,"todo_due":0,"todo_completed":0,"source":"joplin-desktop","source_application":"net.cozic.joplin-desktop","application_data":"","order":1764348818441,"markup_language":2,"is_shared":0,"share_id":"","conflict_original_id":"","master_key_id":"","user_data":"","deleted_time":0},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2025-11-28T21:03:25.944Z
created_time: 2025-11-28T21:03:25.944Z
type_: 13