[高通] IPQ 系列 FAQ1 - 使用 Docker 來快速建立工作環境

關鍵字 :QCADocker

1. 摘要

每個專案開發時, 總是需要針對每個專案, 各自建立自己的開發環境, 但往往這樣的過程總是費時又費力. 如果能讓每個開發者專注於眼前的工作, 快速的建置開發環境, 對開發者來說, 會是一件很美好的事, 對部門或者是公司來說, 也是一件不錯的事.

今天要來淺談如何使用 Docker 來快速建立開發環境. Docker 是一個開放原始專案, 它允許將應用程式自動化部署, 在雲端或內部部署上執行. 所以基本上, 它讓應用程式或是 OS 可以執行在裝有 docker 的任何平台上.

接下來, 我將以自己開發 QCA 的工作環境為例, 來引導如何快速建立工作環境. 

2. 安裝 Docker 套件


首先, 我自己的 Linux 環境是 Ubuntu 20.04. 我們先來在 Ubuntu 20.04 的環境下安裝 Docker.

robert@robert-Virtual-Machine:~$ sudo aptitude update -y
robert@robert-Virtual-Machine:~$ sudo aptitude upgrade -y
robert@robert-Virtual-Machine:~$ sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
robert@robert-Virtual-Machine:~$ sudo apt-get update -ysudo apt-get install docker-ce docker-ce-cli containerd.io

3. 安裝 Ubuntu 16.04


在安裝完 Docker 後, 我們就可以透過 Docker 來建置開發工作環境. 根據 QCA 官方文件建議, 我需要安裝舊版的 Ubuntu 才能去進一步開發, 但是目前我的本機是 Ubuntu 20.04, 這時候就可以透過 Docker 來安裝舊版的 Ubuntu 16.04 image.

使用 docker pull 指令, 將 Ubuntu 16.04 映像檔下載下來
robert@robert-Virtual-Machine:~$  sudo docker pull ubuntu:16.04
[sudo] password for robert:
16.04:Pulling from library/ubuntu
80bce60046fa: Pull complete
55a738a15540: Pull complete
e19cf0706c62: Pull complete
de4cdd6c27d1: Pull complete
Digest: sha256:9775877f420d453ef790e6832d77630a49b32a92b7bedf330adf4d8669f6600e
Status: Downloaded newer image for ubuntu:16.04
docker.io/library/ubuntu:16.04

使用 docker images 檢查 Ubuntu 版本
robert@robert-Virtual-Machine:~$ sudo docker images -a
REPOSITORY   TAG       IMAGE ID       CREATED       SIZEubuntu       16.04     9ff95a467e45   2 weeks ago   135MB
 

4. 啟動 Ubuntu 16.04


在上一個步驟中, 我們已經將 Ubuntu 16.04 image 下載至 Docker 中, 接下來我們就來啟動 Ubuntu 16.04.

robert@robert-Virtual-Machine:~$  sudo docker run -itd --name=16.04 9ff95a467e45 /bin/bash
robert@robert-Virtual-Machine:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
595b9bb6b041 9ff95a467e45 "/bin/bash" 13 seconds ago Up 12 seconds 16.04


執行完上面的指令後, docker 會在容器內安裝 Ubuntu 16.04.

5. 安裝並設定開發環境相關套件


我們已經在容器內執行 Ubuntu 16.04,接著我們將登入 Ubuntu 16.04 載體中並設定相關權限, 與安裝套件.

在此之前, 我們後續需要目前使用者的 id, 目前我的使用者 id 編號是 1000
robert@robert-Virtual-Machine:~$  id
uid=1000(robert) gid=1000(robert) groups=1000(robert),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),120(lpadmin),131(lxd),133(sambashare)

登入 Ubuntu 16.04

robert@robert-Virtual-Machine:~$  sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
595b9bb6b041 9ff95a467e45 "/bin/bash" 13 seconds ago Up 12 seconds 16.04
robert@robert-Virtual-Machine:~$ sudo docker exec -it 16.04 /bin/bash
root@595b9bb6b041:/#

更新系統並安裝相關套件


root@595b9bb6b041:/#  apt-get update -y
root@595b9bb6b041:/# apt-get upgrade -y
root@595b9bb6b041:/# apt-get install sudo
root@595b9bb6b041:/# apt-get install gcc g++ binutils patch bzip2 flex make gettext pkg-config unzip zlib1g-dev libc6-dev subversion libncurses5-dev gawk sharutils curl libxml-parser-perl ocaml-nox ocaml-nox ocaml ocaml-findlib libpcre3-dev binutils-gold python-yaml libssl-dev
root@595b9bb6b041:/# apt-get install git
root@595b9bb6b041:/# apt-get install u-boot-tools
root@595b9bb6b041:/# apt-get install device-tree-compiler
root@595b9bb6b041:/# apt-get install zlib1g-dev libncurses5-dev patch sharutils cmake intltool expat expect
root@595b9bb6b041:/# apt-get install vim tree libfdt-dev mtd-utils libc6-i386 libgl1-mesa-dri:i386

新增使用者 robert

root@595b9bb6b041:/#  adduser robert
Adding user `robert' ...
Adding new group `robert' (1000) ...
Adding new user `robert' (1000) with group `robert' ...
Creating home directory `/home/robert' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for robert
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n]

新增使用者 sudo 權限

...
robert ALL=(ALL:ALL) ALL
...

切換到新增的使用者

root@595b9bb6b041:/#  su robert
robert@595b9bb6b041:/$ cd
robert@595b9bb6b041:~$ pwd
/home/robert


基本上, 上述已經將基礎開發環境已經建立完成, 接著我們離開我們運行的容器
robert@595b9bb6b041:~$  exit
root@595b9bb6b041:/# exit

6. 停止運行容器並將該容器匯出


我們透過 docker stop 將該容器停止運行
robert@robert-Virtual-Machine:~$  sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
595b9bb6b041 9ff95a467e45 "/bin/bash" 41 minutes ago Up 41 minutes 16.04
robert@robert-Virtual-Machine:~$ sudo docker stop 595b9bb6b041

595b9bb6b041
robert@robert-Virtual-Machine:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
595b9bb6b041 9ff95a467e45 "/bin/bash" 43 minutes ago Exited (0) About a minute ago 16.04

接著我們將剛剛建置好的容器給匯出成映像檔, 並指定成 Develop-U16.04.tar
robert@robert-Virtual-Machine:~$  sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
595b9bb6b041 9ff95a467e45 "/bin/bash" 48 minutes ago Exited (0) 7 minutes ago 16.04
robert@robert-Virtual-Machine:~$ sudo docker export 16.04 > Develop-U16.04.tar
robert@robert-Virtual-Machine:~$ ls -al Develop-U16.04.tar
-rw-rw-r-- 1 robert robert 907415040 六 4 13:49 Develop-U16.04.tar

7. 匯入剛剛建立的開發環境


我們將剛剛匯出的容器, 拷貝到另外一個新的機器上, 並將該映像檔匯入
robert@robert-Virtual-Machine:~$  sudo docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
robert@robert-Virtual-Machine:~$
robert@robert-Virtual-Machine:~$ cat Develop-U16.04.tar | sudo docker import - ubuntu:16.04
sha256:82b428b2eec72bd7d192412f7ff0557d2ce593adecc2110533667cfeeaadf298
robert@robert-Virtual-Machine:~$ sudo docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 16.04 82b428b2eec7 12 seconds ago 884MB

8. 啟動容器並掛載目錄


現在我們以經可以透過 docker 的技術, 將開發環境佈屬到裝有 docker 的環境上, 接下來我們將掛載本機的目錄到容器中.

啟動 docker 跟上面的步驟沒有什麼區別, 但我們需要將 QCA 的 Soure Code 放置 Container 中做編譯, 可是我們當初建立的映象檔, 並沒有包含這一部分. 其實我們只需要透過掛載目錄的技巧, 將 QCA 的原生代碼掛載到容器中, 就可以了.

robert@robert-Virtual-Machine:~$  mkdir test
robert@robert-Virtual-Machine:~$
robert@robert-Virtual-Machine:~$ ls
Desktop Develop-U16.04.tar Documents Downloads Music Pictures Public Templates test Videos
robert@robert-Virtual-Machine:~$ cd test/
robert@robert-Virtual-Machine:~/test$ pwd
/home/robert/test
robert@robert-Virtual-Machine:~$ cd
robert@robert-Virtual-Machine:~$ sudo docker run -itd --name=16.04 -v /home/robert/test:/home/robert ubuntu:16.04 /bin/bash 3ba5264c38ca8af4527e1c71f045c3359e96704000cca4c6d33faa281f0b21a4
robert@robert-Virtual-Machine:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ba5264c38ca ubuntu:16.04 "/bin/bash" About a minute ago Up About a minute 16.04


我們已經在新的機器上, 運行剛剛匯入的映象檔, 建立新的容器並掛載 test 目錄. 接下來,我們測試看看 test 目錄中, 使否有正確掛載到容器中.

robert@robert-Virtual-Machine:~/test$  touch 123
robert@robert-Virtual-Machine:~/test$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ba5264c38ca ubuntu:16.04 "/bin/bash" 9 minutes ago Up 9 minutes 16.04
robert@robert-Virtual-Machine:~/test$ ls -al
total 8
drwxrwxr-x 2 robert robert 4096 六 4 14:26 .
drwxr-xr-x 16 robert robert 4096 六 4 14:14 ..
-rw-rw-r-- 1 robert robert 0 六 4 14:26 123
robert@robert-Virtual-Machine:~/test$ sudo docker exec -it 16.04 /bin/bash
root@3ba5264c38ca:/# su robert
robert@3ba5264c38ca:/$ cd
robert@3ba5264c38ca:~$ ls
123
robert@3ba5264c38ca:~$

9. 結論


Docker 是一個很好用的工具, 我們可以透過它來完成很多事情. 一般我都會將 Docker 常用的指令, 撰寫成 Script, 透過 Script 直接執行即可. 至於 docker 相關的指令, 不在今天討論的範圍, 有興趣的朋友, 可以上網去查詢.

#!/bin/sh#!/bin/sh
[ -z $1 ] && echo "Please input your action[run|exec|st|start|stop]" && exit
docker_name="16.04"
case "$1" in       
"run") 
                id=`docker images -a|grep ubuntu|awk '{print $3}'`
                docker $1 -itd --name=$docker_name -v /home/robert/test:/home/robert $id /bin/bash
                ;;       
"exec")
                docker $1 -it $docker_name /bin/bash
                ;;       
"status")
                echo "Docker Images Status"
                docker images -a|grep "ubuntu"
                echo "Docker Container Status"
                docker ps -a|grep $docker_name                ;;       
"start")
                id=`docker ps -a|grep $docker_name|awk '{print $1}'` 
                docker $1 $id
                ;;       
"stop")
                id=`docker ps -a|grep $docker_name|awk '{print $1}'`
                docker $1 $id
                ;;       
*)               
                echo "The command - $1 is error."
               ;;
esac

10. 參考


1. [什麼是 Dokcer]
2. [認識Docker 容器與鏡像]
3. [Docker 基本指令]

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

評論