docker編譯安卓源碼
⑴ Android docker中編譯AOSP google官方的docker鏡像
https://android.googlesource.com/platform/build/+/master/tools/docker
First, build the image:
⑵ 在docker編譯之後還能看到原有文件嗎
還能。ocker是一個開源的應用容旦冊器引擎,讓開發者可以打包他們的應頌遲嘩用以及依賴包到一個可移植的鏡像中,然後發布到任何流行的linux或Windows操作系野行統的機器上,也可以實現虛擬化,在編譯之後還能看到原有文件,在image里,image包含了docker源碼編譯所需的所有文件。
⑶ 如何利用 Docker 環境加速 Android 應用的構建
極大的縮短安卓開發答粗到測試到產品到渠道的距離。
給安卓程序員減輕裂舉坦負擔。
Google做的環境已經特別到位了,放到docker裡面明顯不會有多大的坑(誤,肆桐逃)。
⑷ 如何在"特殊"的網路環境下編譯 Docker
由於 Docker 編譯需要依賴於 Docker Daemon ,所以只能在 64 位的 Linux 環境下先安裝 Docker 程序,再從 Github 上克隆 Docker 的代碼進行編譯。
在 Docker 的目錄下執行 make 命令將默認執行 Makefile 中 make binary 指令進行編譯。
?
default: binary
all: build
$(DOCKER_RUN_DOCKER) hack/make.sh
binary: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary
cross: build
$(DOCKER_RUN_DOCKER) hack/make.sh binary cross
從以上的 Makefile 可以看出,執行 make、make binary、make all 或 make cross 都可以得到可運行的 Docker 程序。
在 Mac OS 環境下使用 brew 的命令安裝 Docker ,只能得到一個 docker client 的二進製程序,如果以 daemon 的方式運行,會得到 『This is a client-only binary - running the Docker daemon is not supported.』 的錯誤提示信息。
方法 1.
使用 VirtualBox 或者 VMWare Workstation 安裝一個 Linux 的虛擬機。宿主機使用 VPN 等方案使網路「正常」訪問各種「服務」,虛擬機網卡使用 NAT 模式。在 Linux 虛擬機內使用 make 進行編譯 Docker 不會有任何網路問題。只是編譯速度受限於 VPN 等網路解決方案,有可能等待時間很長。
方法 2.
Docker 每次發布新版本,都會在 docker-dev 的鏡像倉庫發布一個新的標簽,這個鏡像倉庫包含了編譯 Docker 鏡像所依賴的所有環境,只需替換 Docker 代碼目錄下的 Dockerfile 即可實現編譯 Docker 。
?
FROM docker.cn/docker/docker-dev:v1.2.0
VOLUME /var/lib/docker
WORKDIR /go/src/github.com/docker/docker
ENV DOCKER_BUILDTAGS apparmor selinux
ENTRYPOINT [「hack/dind」]
COPY . /go/src/github.com/docker/docker
Dockerfile 中只保留必要的步驟就可以實現編譯了。
方法 3.
對 Docker 代碼中的 Docker 進行徹底的改造,用國內的各種鏡像替換其中不能在「正常」網路條件下訪問的鏡像,使得代碼能夠快速編譯通過。
?
FROM docker.cn/docker/ubuntu:14.04.1
MAINTAINER Meaglith Ma <[email protected]> (@genedna)
RUN echo "deb http://mirrors.aliyun.com/ubuntu trusty main universe" > /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty universe" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty universe" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty-updates universe" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates universe" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted" >> /etc/apt/sources.list && echo "deb http://mirrors.aliyun.com/ubuntu/ trusty-security universe" >> /etc/apt/sources.list && echo "deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
btrfs-tools \
build-essential \
curl \
dpkg-sig \
git \
iptables \
libapparmor-dev \
libcap-dev \
libsqlite3-dev \
lxc=1.0* \
mercurial \
parallel \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.0* \
unzip \
--no-install-recommends
RUN git clone --no-checkout https://coding.net/genedna/lvm2.git /usr/local/lvm2 && cd /usr/local/lvm2 && git checkout -q v2_02_103
RUN cd /usr/local/lvm2 && ./configure --enable-static_link && make device-mapper && make install_device-mapper
RUN curl -sSL http://docker-cn.qiniudn.com/go1.3.1.src.tar.gz | tar -v -C /usr/local -xz
ENV PATH /usr/local/go/bin:$PATH
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
ENV PATH /go/bin:$PATH
RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1
ENV DOCKER_CROSSPLATFORMS \
linux/386 linux/arm \
darwin/amd64 darwin/386 \
freebsd/amd64 freebsd/386 freebsd/arm
ENV GOARM 5
RUN cd /usr/local/go/src && bash -xc 'for platform in $DOCKER_CROSSPLATFORMS; do GOOS=${platform%/*} GOARCH=${platform##*/} ./make.bash --no-clean 2>&1; done'
RUN mkdir -p /go/src/github.com/gpmgo \
&& cd /go/src/github.com/gpmgo \
&& curl -o gopm.zip http://gopm.io/api/v1/download?pkgname=github.com/gpmgo/gopm\&revision=dev --location \
&& unzip gopm.zip \
&& mv $(ls | grep "gopm-") gopm \
&& rm gopm.zip \
&& cd gopm \
&& go install
RUN gopm bin -v code.google.com/p/go.tools/cmd/cover
RUN gem sources --remove https://rubygems.org/ \
&& gem sources -a https://ruby.taobao.org/ \
&& gem install --no-rdoc --no-ri fpm --version 1.0.2
RUN gopm bin -v -d /go/bin github.com/cpuguy83/go-md2man@tag:v1
RUN git clone -b buildroot-2014.02 https://github.com/jpetazzo/docker-busybox.git /docker-busybox
RUN /bin/echo -e '[default]\naccess_key=$AWS_ACCESS_KEY\nsecret_key=$AWS_SECRET_KEY' > /.s3cfg
RUN git config --global user.email '[email protected]'
RUN groupadd -r docker
RUN useradd --create-home --gid docker unprivilegeser
VOLUME /var/lib/docker
WORKDIR /go/src/github.com/docker/docker
ENV DOCKER_BUILDTAGS apparmor selinux
ENTRYPOINT ["hack/dind"]
COPY . /go/src/github.com/docker/docker
以上的命令把 Ubuntu 鏡像中的源替換為國內速度較快的阿里源;把 lvm2 鏡像到國內的 Git 託管服務 coding.net;從 七牛雲存儲 保存的 Golang 源碼進行獲取和編譯;使用 gopm 下載編譯所需要的 Library ;最後把其中 gem 源切換到淘寶。至此,可以在「特殊」的網路條件下快速編譯 Docker 。
⑸ docker鏡像ubuntu:14.04內mkisofs: command not found
環境:sudo docker pull ubuntu:14.04 # docker默認都是64位系統
mkisofs可將指定的目錄與文件做成ISO 9660格式的映像文件,以配閉供刻錄光碟。使用ubuntu14.04 的docker鏡像編譯android源碼時:
拋出錯誤:
解決過程:
1、更新軟體源
把以下軟體源禪薯添加進去賀賣者,網易163更新伺服器(廣東廣州電信/聯通千兆雙線接入),包含其他開源鏡像:
2、執行安裝
3、檢查是否存在mkisofs命令
$ mkisofs
genisoimage: Missing pathspec.
Usage: genisoimage [options] -o file directory ...
Use genisoimage -help
to get a list of valid options.
Report problems to [email protected] .
可以看到 mkisofs 是通過軟鏈接到 genisoimage 中去的,所以安裝 genisoimage package就能有 mkisofs命令
⑹ 在docker搭建android編譯打包環境實踐
輸入如下命令
之後就進入了容器shell命令衡頌界面
git clone https://github.com/hellsam/EmptyProject.git
進入EmptyProject文件夾,輸入如下命令
輸入如下命令
等待命令執行完成(第一態褲次會比較慢)咐閉鄭,最終apk地址 app/build/outputs/apk/release/app-release.apk
至此我們完成了在docker上搭建了android打包編譯環境,並成功編譯出了apk文件。
⑺ docker可以不在容器裡面編譯
不可以。
因為docker的源碼需要在容器禪物中進行編譯,因此必須要有docker安裝在host上,所以docker不可以不在容器裡面編譯。
Docker是一個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到一個枯局可移植的容器中,然後發布到任何流行的Linux機器上,也沒襲讓可以實現虛擬化。
⑻ 如何編譯docker源碼
經過研究docker的官方編譯腳步,發現本地編譯也很簡單,只需要在docker源碼的目錄下執行如下命令即可:
./hack/make.sh binary
上面這條命令就只會生成docker的二進制文件,不過肯定不會這么順利的,執行這個命令你就會發現錯誤。如果第一次執行報的錯誤應該是找不到相應的go依賴包。那麼現在就開始解決第一個問題,go依賴包。
解決go依賴包最直接的方法就一個一個去github或者其他地方去下載到本地,但是這樣做很麻煩,docker依賴的go語言包很多,然後依賴包可能又依賴其他包。這里有辯早一個簡單實用的辦法,也是go語言管理項目的方便之處。通過go get命令來自動下載,例如發現報錯的是docker某一個目錄下的依賴包,那麼可以如下執行:
go get -v ./src/github.com/docker/docker/...
這條命令執行以後整個docker目錄下源文件依賴的包都會被自動下載。如果發現其他目錄下源文件也報同樣的錯誤,可以按照次方法解決。不過這里需要強調一點, 這些下載都是會下載最新的包,如果編譯老的docker肯定會出問題 ,如果編譯最新的docker代碼肯定不會有問題,因為官方的編譯是這種方式。
上面執行的命令都是建立在go語言環境建立成功的基礎上,我安裝的go遇到是1.3.3版本的,採用源碼方式安裝。安裝在/export/servers/go下面,然後所有的go語言工程源碼目錄放在 /export/servers/gopath。然後配置環境變數在用戶的根目錄下的.bashrc文件裡面如下:
export GOPATH=/export/servers/gopath
export GOROOT=/export/servers/go
export GOARCH=amd64
export GOOS=linux
然後docker的代碼目錄如下:/export/servers/gopath/src/github.com/docker/docker。這樣才能在gopath下面進行依賴包的下載。通過上面的方法把所有依賴包下載完以模鉛後就可以進行編譯了。
在繼續編譯的過程中還會遇到旦灶好缺少c語言依賴包缺少的問題,主要有三個,(1)sqlite3;(2)device-mapper;(3)btrfs.
第一個sqlite3可以使用如下命令安裝依賴:yum install sqlite-devel.x86_64
第二個在官方的dockerfile文件裡面有解決方案,執行如下命令:
git clone --no-checkout https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2 && cd /usr/local/lvm2 && git checkout -q v2_02_103
cd /usr/local/lvm2 && ./configure --enable-static_link && make device-mapper && make install_device-mapper
⑼ 如何編譯Docker源碼
本文根據docker官方給出的docker代碼編譯環境搭建指南做更深入的分析。官方給出的指導比較簡單,但是由於國內的網路問題經常會編譯失敗,了解了編譯步驟後,也可以結合自身遇到的網路問題進行「規避」。
docker的編譯環境實際上是創建一個docker容器,在容器中對代碼進行編譯。 如果想快速的查看編譯環境搭建指導,而不關注環境搭建的機制和細節,可以直接跳到最後一章「總結」。
前提
機器上已經安裝了docker,因為編譯環境是個docker容器,所以要事先有docker(daemon),後面會創建個編譯環境容器,在容器裡面編譯代碼。本文中使用物理機,物理機上運行著docker (daemon)。
機器(物理機)上安裝了git 。 後續使用git下載docker源碼
機器(物理機)上安裝了make。
下載ubuntu 14.04的docker鏡像
下載docker源碼
git clone
會把代碼下載到當前目錄下,後面會把代碼拷貝到容器中。
編譯前分析
官方給的編譯方法是make build 和 make binary等。下面先分析Makefile,看懂Makefile後,編譯環境的准備流程就比較清楚了。
Makefile
在下載的docker源碼中可以看到它的Makefile,Makefile中比較關鍵的幾個參數:
DOCKER_MOUNT := $(if $(BIND_DIR),-v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/docker/docker/$(BIND_DIR)") DOCKER_MOUNT 表示創建容器時的mount參數。因為編譯環境是一個容器,在後續的步驟中啟動容器時使用DOCKER_MOUNT參數,會將物理機上的目錄mount給容器容器,容器中該目錄是編譯生成docker二進制文件的目錄。
DOCKER_FLAGS := docker run --rm -i --privileged $(DOCKER_ENVS) $(DOCKER_MOUNT) 這是後面創建docker容器時的命令行的一部分,其中包含了前面的DOCKER_MOUNT參數。
DOCKER_IMAGE := docker-dev$(if $(GIT_BRANCH),:$(GIT_BRANCH)) 這是docker image參數,鏡像的名字是docker-dev,以當前git中docker版本作為tag名。這個鏡像是在make build一步做出來的。
DOCKER_RUN_DOCKER := $(DOCKER_FLAGS) "$(DOCKER_IMAGE)" 創建docker容器的命令行,組合了前面的DOCKER_FLAGS 和 DOCKER_IMAGE 。 從命令行中可以看出,啟動容器使用的參數有 --rm -i --privileged,使用了一些環境變數,還有使用了-v參數把物理機上目錄mount給容器,在容器中編譯好二進制文件後放到該目錄中,在物理機上就能獲得docker二進制文件。啟動的的docker 容器鏡像名字是docker-dev。下文會介紹docker-dev鏡像是怎麼來的。
由於官方給出的「構建編譯環境」的方法是執行 make build,下面在Makefile中看到build分支是這樣的:
make build時會調用 docker build -t "$(DOCKER_IMAGE)" . 去製作一個叫做DOCKER_IMAGE的鏡像。
進行源碼編譯的方式是執行 make binary來編譯代碼,在Makefile中make binary的分支如下:
make binary除了進行 make build以外,會執行$(DOCKER_RUN_DOCKER),即上文提到的docker run命令行。由於執行過了build,會build出來docker-dev鏡像,所以在docker run時直接使用前面build出來的鏡像。docker run時的命令行參數是hack/make.sh binary。make binary的過程實際上是創建一個容器,在容器中執行hack/make.sh binary腳本。接下來會詳細介紹make build和make binary所做的內容。
make build
根據官方的指導,先執行make build來搭建編譯環境。上面分析了,make build實際上是製作了一個鏡像,這個鏡像里會包含編譯代碼所需的環境。下面來介紹下這個鏡像。
Dockerfile
在和Makefile相同的目錄下(源碼的根目錄),有Dockerfile。執行make build 相當於調用docker build,使用的就是該Dockerfile。Dockerfile中的幾個主要步驟(有些步驟這里略過):
FROM ubuntu:14.04 使用ubuntu 14.04作為基礎鏡像;在宿主機上,要事先下載好ubuntu 14.04鏡像。
安裝一些編譯需要的軟體;
用git下載lvm2源碼,並編譯安裝;
下載並安裝GO 1.5.1;
安裝GO相關的tools 可以做code coverage test 、 go lint等代碼檢查
安裝registry和notary server;
安裝docker-py 後面跑集成測試用的
將物理機的contrib/download-frozen-image.sh 腳本拷貝到鏡像中/go/src/github.com/docker/docker/contrib/
運行contrib/download-frozen-image.sh 製作鏡像 實際上這一步只是下載了3個鏡像的tar文件。注意:docker build相當於創建一個臨時的容器(在臨時的容器中執行Dockerfile中的每一步,最後在保存成鏡像),「運行contrib/download-frozen-image.sh 製作鏡像」這個動作出現在Dockerfile中,相當於在docker build所創建的臨時的容器中下載docker鏡像,有docker-in-docker容器嵌套的概念。下一小節會對download-frozen-image.sh腳本做詳細分析。
ENTRYPOINT ["hack/dind"] 做出來的鏡像,使用它啟動的容器可以自動運行源碼目錄中的hack/dind腳本。 dind這個腳本是a wrapper script which allows docker to be run inside a docker container 。後面的小節會對hack/dind腳本做詳細的分析。
COPY . /go/src/github.com/docker/docker 把物理機上的docker源碼文件打入到鏡像中
download-frozen-image.sh腳本
上一小節里提到,在Dockerfile中,有一步會調用contrib/download-frozen-image.sh ,它主要作用是下載3個鏡像的tar包,供後續docker load。在Dockerfile中的調用方式如下:
download-frozen-image.sh腳本中會依次解析參數,其中/docker-frozen-images作為base dir,後面下載的東西全放到這里。之後的3個參數是鏡像,裡麵包含了鏡像名(例如busybox)、鏡像tag(例如latest)、鏡像id(例如),後面會在循環中依次下載這3個鏡像的tar文件。
download-frozen-image.sh腳本中會通過curl從registry上獲取如下信息:
token:獲取token,後面curl獲取的其他信息時都需要使用token。例如本例中 token='signature=,repository="library/busybox",access=read'
ancestryJson:把鏡像相關聯的歷史層次的id也都獲取到,因為每一層的tar都需要下載。本例中 ancestryJson='["", ""]'
這里可以看到這個鏡像只有2層,兩層的id這里都列了出來。 每個鏡像包含的層數不同,例如。第三個鏡像jess/unshare共有10層。
VERSION、json、tar: 每一層鏡像id的目錄下,都下載這3個文件,其中VERSION文件內容目前都是「1.0」,json文件是該層鏡像的json文件,tar文件是該層鏡像的真正內容,以.tar保存。
下載好的各層鏡像目錄結構如下:
$ls
$tree
hack/dind腳本
在Dockerfile中,ENTRYPOINT ["hack/dind"] ,表示在鏡像啟動後,運行該腳本,下面分析一下這個腳本的功能。
腳本在代碼根目錄下的hack目錄中,作者對腳本的描述是 DinD: a wrapper script which allows docker to be run inside a docker container.
就是可以在docker容器中創建docker容器。它就做了一個事,那就是在容器中創建好cgroup目錄,並把各個cgroup子系統mount上來。
為了方便理解,我們可以先看看物理機。在宿主機上如果創建docker容器,需要宿主機上必須事先mount cgroup子系統,因為cgroup是docker容器的一個依賴。同理docker-in-docker也要求外層的docker容器中有cgroup子系統,dind腳本在容器啟動後,先去/proc/1/cgroup中獲取cgroup子系統,然後依次使用mount命令,將cgroup mount上來,例如mount -n -t cgroup -o "cpuset" cgroup "/cgroup/cpuset"
最終在運行make build後,會製作出一個叫docker-dev的鏡像。
make binary
執行make binary 就可以編譯出docker二進制文件。編譯出來的二進制文件在源碼目錄下的bundles/1.10.0-dev/binary/docker-1.10.0-dev ,其中還包含md5和sha256文件。
Makefile中的binary
Makefile中關於make binary流程是
先執行build,即上一節介紹的,製作docker-dev編譯環境鏡像。
再執行DOCKER_RUN_DOCKER,創建容器,DOCKER_RUN_DOCKER就是執行docker run,使用docker-dev鏡像啟動容器,並且會mount -v 將容器生成二進制文件的路徑與宿主機共享。DOCKER_RUN_DOCKER在「編譯前分析」一章中有介紹。啟動的容器運行的命令行是 hack/make.sh binary 。docker run完整的形式如下:
docker run --rm -i --privileged -e BUILDFLAGS -e DOCKER_CLIENTONLY -e DOCKER_DEBUG -e DOCKER_EXECDRIVER -e DOCKER_EXPERIMENTAL -e DOCKER_REMAP_ROOT -e DOCKER_GRAPHDRIVER -e DOCKER_STORAGE_OPTS -e DOCKER_USERLANDPROXY -e TESTDIRS -e TESTFLAGS -e TIMEOUT -v "/home/mu/src/docker/docker/bundles:/go/src/github.com/docker/docker/bundles" -t "docker-dev:master" hack/make.sh binary
hack/make.sh腳本
上一節提到的make binary中創建的容器啟動命令是hack/make.sh binary,運行容器中的(docker源碼目錄下的)hack/make.sh腳本,參數為binary。
make.sh中根據傳入的參數組裝後續編譯用的flags(BUILDFLAGS),最後根據傳入的參數依次調用 hack/make/目錄下對應的腳本。例如我們的操作中傳入的參數只有一個binary。那麼在make.sh的最後,會調用hack/make/binary腳本。
hack/make/binary腳本中,就是直接調用go build進行編譯了,其中會使用BUILDFLAGS LDFLAGS LDFLAGS_STATIC_DOCKER等編譯選項。
如果最終生成的docker二進制文件不在bundles/1.10.0-dev/binary/目錄下,那麼可能是編譯參數BINDDIR設置的不正確,可以在執行make binary時增加BINDDIR參數,例如
make BINDDIR=. binary , 將BINDDIR設置為當前目錄。
總結
編譯步驟總結:
1、編譯前在物理機上安裝好make、git,並下載好docker代碼。下載好ubuntu:14.04鏡像
2、執行make build 。這步執行完會在物理機上創建出一個docker-dev的鏡像。
3、執行make binary 。 這步會使用docker-dev鏡像啟動一個容器,在容器中編譯docker代碼。編譯完成後在物理機上直接可以看到二進制文件。默認二進制文件在 bundles/1.10.0-dev/binary/目錄下
4、docker代碼里有很多test,可以使用此套編譯環境執行test,例如 make test 。 更多參數可以看Makefile
搭建環境心得:
1、在make build時,使用Dockerfile創建製作鏡像,這個鏡像有40多層,其中一層失敗就會導致整個build過程失敗。由於Dockerfile中很多步驟是要連到國外的網站去下載東西,很容易失敗。好在docker build有cache機制,如果前面的層成功了,下次重新build時會使用cache跳過,節省了很多時間。所以如果make build中途失敗(一般是由於國內連國外的網路原因),只要重新執行make build就會在上次失敗的地方繼續,多試幾次可以成功。
2、如果其他人已經build出了docker-dev鏡像,可以把它下載到自己的環境上。這樣在自己make build時,會跳過那些已經在本地存在的層,可以節省時間。
3、每一次編譯會自動刪除掉前面已經生成的二進制文件,所以不用擔心二進制文件不是最新的問題。