### 前言
菜雞玩家第一次接觸Linux的buildroot環境,還在熟悉中。對于長期使用Linux命令行的、熟悉OpenHarmony構建系統的人來說,更清楚編譯環境對小白來說有多蛋疼。作為一個重度的docker環境使用者,以及小白折騰編譯環境的勸退佬來說,有一句話特別想對想學Linux的小白說。
本次制作鏡像所需的文件已打包放在附件,想直接使用的,可以直接從**第2節** **創建docker鏡像**開始。不想自己制作的,可以從**第3節** **創建docker容器**開始。
---
**你有空去折騰Linux的編譯環境,還不如來學學Docker鏡像的制作**
---
#### 用docker制作編譯環境的好處
1. docker鏡像的制作腳本,可以添加注釋,作為學習過程記錄和知識積累。
2. 學習docker鏡像制作,能更好的理解Linux權限
3. 加深對系統目錄的理解
4. 重裝系統時,不需要浪費大量時間回憶環境搭建過程
5. docker容器玩壞了沒關系,重新用鏡像創建一個新的就行
6. 工具鏈更新時,可以通過快速調整制作腳本快速升級環境
7. 啟動快速,培養命令行使用習慣
---
#### docker的缺點
1. win下不能調用USB設備(無法直接燒錄)
2. docker需要學習和理解(基本上花2小時在B站看一下入門教程即可)
3. 重度命令行工具(使用命令行完成幾乎所有操作)
---
#### 開始學習制作docker鏡像
準備工作:安裝docker(百度很多教程,沒啥好說,不廢話),然后將附件里的壓縮包解壓縮到任意目錄,在命令行中進入該目錄下。
1. 編制制作腳本文件tina_env.dockfile。
這里我已經制作好了,實際上腳本也沒什么復雜的東西。簡單來說,也就是FROM命令指定鏡像的基礎包。ENV命令設置鏡像的環境變量。WORKDIR命令設置進入容器的默認路徑(本鏡像默認把源碼掛載在/mnt目錄,所以工作區也設置為該路徑)。COPY命令將主機目錄的內容復制到鏡像內。RUN命令會在構建鏡像時進入鏡像環境中執行相關的Linux指令(比方說給鏡像安裝指定的軟件包,文件的處理等)。
我們看一下本次制作tina_env的腳本文件。文件開頭可以看到以下內容(均有注釋,就不一一解釋了):
```
# 使用python2.7的精簡版debian鏡像作為基礎
FROM python:2.7-slim-buster
# 調整時區
ENV TZ "Asia/Shanghai"
# 設置默認工作路徑
WORKDIR /mnt
# 拷貝主機的目錄內容(.bashrc以及可執行的repo程序)到鏡像內
COPY Docker/vuser/* /root/
# 添加普通用戶組
RUN groupadd -g 1000 tina && \
# 添加普通用戶
useradd vuser -r -m --uid 1000 -g tina --shell /bin/bash && \
# 復制Powerline至/usr/bin目錄,并調整權限
mv /root/powerline-go /usr/bin/powerline-go && chmod 755 /usr/bin/powerline-go && \
# 為root用戶添加python國內源
mkdir ~/.pip && \
echo '[global]' >> ~/.pip/pip.conf && \
echo 'index-url = https://pypi.tuna.tsinghua.edu.cn/simple' >> ~/.pip/pip.conf && \
echo '[install]' >> ~/.pip/pip.conf && \
echo 'trusted-host = https://pypi.tuna.tsinghua.edu.cn' >> ~/.pip/pip.conf && \
# 復制pip國內源配置至普通用戶
cp -rv ~/.pip /home/vuser/ && chown -R vuser:tina /home/vuser/.pip && \
# 修改系統軟件包國內源
sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
# 添加 i386 環境支持
dpkg --add-architecture i386 && \
apt-get update && apt-get install apt-utils -y && \
# 安裝常見軟件庫
apt-get install curl wget pv git lbzip2 libncurses5 libncursesw5 nano -y && \
# 安裝buildroot 必須依賴的軟件庫
apt-get install sed gawk make binutils diffutils gcc g++ bash patch gzip bzip2 perl \
tar cpio unzip rsync bc gawk libncurses-dev libssl-dev zlib1g-dev xz-utils file -y && \
# 安裝 i386環境支持庫
apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 busybox rsync lzma -y && \
# 清理緩存,減少鏡像體積
apt-get clean && \
# 復制bashrc配置文件到vuser用戶
cd /root && cp .bashrc .bash_aliases /home/vuser/ && chown -R vuser:tina /home/vuser && \
# 創建工具鏈目錄
mkdir /opt/toolchains && chmod 666 /opt/toolchains
# 容器創建后,默認登陸以bash作為登陸環境
CMD ["/bin/bash"]
```
2. 創建docker鏡像
在磁盤的任意位置創建一個任意目錄(比如docker_build), 然后把附件的壓縮包解壓縮到這個目錄里,然后用命令行進入這個目錄(docker_build)。在命令行中執行以下命令(需要將walker2048替換成你自己的dockerhub用戶名):
```
docker build -t walker2048/tina_env -f Docker/tina_env.dockerfile --network host .
```
命令解析:
build參數:告訴docker要執行創建鏡像的工作
-t walker2048/tina_env 參數: 告訴docker這個鏡像的tag標簽(walker2048/tina_env)。可以理解成鏡像的標識符(類似地址和姓名),這個tag標簽是可以修改的,把鏡像上傳到dockerhub上也需要指定正確的標簽。
-f Docker/tina_env.dockerfile 參數: 告訴docker使用哪一個構建腳本(可以使用絕對路徑和相對路徑)
--network host參數: 告訴docker使用主機的網絡配置
最后的. 參數:將當前目錄的所有內容傳遞給docker作為臨時輸入內容(COPY命令需要使用)。
---
正確執行命令后,網絡正常的情況下,大概只需要5分鐘左右,就順利完成鏡像構建了。命令行輸出輸出類似下圖:
```
Sending build context to Docker daemon 95.64MB
Step 1/7 : FROM python:2.7-slim-buster
---> eeb27ee6b893
Step 2/7 : ENV TZ "Asia/Shanghai"
---> Using cache
---> 0c0e432b82be
Step 3/7 : WORKDIR /mnt
---> Using cache
---> 0d54e5487ee3
Step 4/7 : COPY Docker/vuser/* /root/
---> Using cache
---> 3e1598cc56a3
Step 5/7 : COPY Docker/bin/* /usr/bin/
---> Using cache
---> 40895711f1dc
Step 6/7 : RUN groupadd -g 1000 tina && useradd vuser -r -m --uid 1000 -g tina --shell /bin/bash && mv /root/powerline-go /usr/bin/powerline-go && chmod 755 /usr/bin/powerline-go && mkdir ~/.pip && echo '[global]'
>> ~/.pip/pip.conf && echo 'index-url = https://pypi.tuna.tsinghua.edu.cn/simple' >> ~/.pip/pip.conf && echo '[install]' >> ~/.pip/pip.conf && echo 'trusted-host = https://pypi.tuna.tsinghua.edu.cn' >> ~/.pip/pip.conf
&& cp -rv ~/.pip /home/vuser/ && chown -R vuser:tina /home/vuser/.pip && sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && dpkg --add-architecture i386 && apt-get update && apt-get install apt-utils -y && apt-get install curl wget patch pv git zip lbzip2 libncurses5 libncursesw5 nano -y && apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 busybox rsync lzma -y && apt-get clean && cd /root && cp .bashrc .bash_aliases /home/vuser/ && chown -R vuser:tina /home/vuser && mkdir /opt/toolchains && chmod 666 /opt/toolchains
##
篇幅原因,中間省略各種軟件源更新和軟件包安裝的內容
##
---> Using cache
---> 3a44cb328437
Step 7/7 : CMD ["/bin/bash"]
---> Using cache
---> 6b65b7402ecd
Successfully built 6b65b7402ecd
Successfully tagged walker2048/tina_env:latest
```
當我們看到所有的步驟(Step)都正確執行了,最后也成功生成了鏡像的時候,就可以開始下一步創建docker容器了。
3. 創建docker容器
創建容器前,需要先理解一下創建容器的一些基礎知識。
3.1 容器類似獨立的虛擬機,除了掛載上去的目錄,文件系統和寄主機是不相通的。
3.2 可以創建名稱不同的、但是使用的鏡像相同的容器。容器間是獨立的關系。
3.3 容器網絡使用方式需要指定,一般編譯服務器無特殊要求的,可以直接指定使用host網絡。
3.4 如果是Linux系統,想讓docker容器訪問USB設備,可以使用--privileged參數開啟。
3.5 創建容器(虛擬機)后,下次使用不需要重新創建。
Linux或者Bash環境使用以下命令
```
docker run -it --name tina_build \
--net=host \
--privileged \
-v /mnt/IoT:/mnt \
walker2048/tina_env
```
Windows環境使用以下命令
```
docker run -it --name tina_build --net=host -v /mnt/IoT:/mnt walker2048/tina_env
```
參數解析:
run 參數: 告訴docker需要創建容器
-it 參數: 創建完畢后自動運行容器時,使用命令行交互方式運行(開啟這個參數才能使用命令行交互)
--name tina_build 參數: 告訴docker把這個容器命名為tina_build(后期運行容器需要使用這個)
--net=host 參數:指定容器的網絡模式為host模式(和主機同一個網絡)
--privileged 參數:特權模式,Linux環境下才有用,開啟后可以訪問USB設備
-v /mnt/IoT:/mnt 參數:掛載寄主機的/mnt/IoT目錄到容器的/mnt目錄(都需要使用絕對路徑,文件雙方共享,可讀寫)
walker2048/tina_env 參數: 告訴docker使用哪個鏡像來創建容器。
進入容器后,命令行提示內容如下(容器默認使用了powerline-go,簡單美化了一下):
repo程序需要配置用戶信息,所以只能自行配置和安裝 #docker# 。
此時需要給vuser用戶添加密碼(只需要執行一次,沒有密碼不能使用login命令切換用戶),在容器的命令行輸入
```
```
> passwd vuser
然后就可以用login命令切換到vuser用戶了。切換用戶后就可以按Tina SDK的說明下載和編譯源碼了(為什么要切換用戶,因為和寄主機子共享了目錄,如果寄主機子是Linux環境,用root用戶操作會影響寄主機對目錄的讀寫)。保持良好的用戶習慣是個好事兒。一般情況下,Linux環境的常規用戶ID是1000開始的。
4. 退出容器和重新運行環境的方法。
4.1 退出容器。
在容器命令行輸入exit(如果之前用root用戶進入容器,然后使用login命令切換用戶的,需要退出至少兩次)。或者直接關閉命令行。
4.2 容器未停止時進入容器的方式(-u 參數指定用戶為root或者vuser):
> docker exec -it -u root tina_build bash
若命令行提示容器為停止狀態(或者寄主機重啟過),需要先使用以下命令開啟容器。
> docker start tina_build
也可以通過-d參數,告訴docker以守護形式長時間開啟容器(直到使用命令行關閉或者寄主機關機)
#### 本次分享的內容就是這些,希望能幫助到有需要的朋友。
因為這邊不能上傳附件,.bashrc內容附在最后
# ~/.bashrc: executed by bash(1) for non-login shells. # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) # for examples # If not running interactively, don't do anything case $- in *i*) ;; *) return;; esac # don't put duplicate lines or lines starting with space in the history. # See bash(1) for more options HISTCONTROL=ignoreboth # append to the history file, don't overwrite it shopt -s histappend # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) HISTSIZE=1000 HISTFILESIZE=2000 # check the window size after each command and, if necessary, # update the values of LINES and COLUMNS. shopt -s checkwinsize # If set, the pattern "**" used in a pathname expansion context will # match all files and zero or more directories and subdirectories. #shopt -s globstar # make less more friendly for non-text input files, see lesspipe(1) #[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" # set variable identifying the chroot you work in (used in the prompt below) if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then debian_chroot=$(cat /etc/debian_chroot) fi # set a fancy prompt (non-color, unless we know we "want" color) case "$TERM" in xterm-color|*-256color) color_prompt=yes;; esac # uncomment for a colored prompt, if the terminal has the capability; turned # off by default to not distract the user: the focus in a terminal window # should be on the output of commands, not on the prompt #force_color_prompt=yes if [ -n "$force_color_prompt" ]; then if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then # We have color support; assume it's compliant with Ecma-48 # (ISO/IEC-6429). (Lack of such support is extremely rare, and such # a case would tend to support setf rather than setaf.) color_prompt=yes else color_prompt= fi fi if [ "$color_prompt" = yes ]; then PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' else PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' fi unset color_prompt force_color_prompt # If this is an xterm set the title to user@host:dir case "$TERM" in xterm*|rxvt*) PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" ;; *) ;; esac # enable color support of ls and also add handy aliases if [ -x /usr/bin/dircolors ]; then test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" alias ls='ls --color=auto' #alias dir='dir --color=auto' #alias vdir='vdir --color=auto' #alias grep='grep --color=auto' #alias fgrep='fgrep --color=auto' #alias egrep='egrep --color=auto' fi # colored GCC warnings and errors #export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' # some more ls aliases #alias ll='ls -l' #alias la='ls -A' #alias l='ls -CF' # Alias definitions. # You may want to put all your additions into a separate file like # ~/.bash_aliases, instead of adding them here directly. # See /usr/share/doc/bash-doc/examples in the bash-doc package. if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases fi # enable programmable completion features (you don't need to enable # this, if it's already enabled in /etc/bash.bashrc and /etc/profile # sources /etc/bash.bashrc). if ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then . /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then . /etc/bash_completion fi fi export PATH=/home/vuser/.bin:$PATH export PATH=/opt/toolchains:$PATH function _update_ps1() { PS1="$(powerline-go -error $? -cwd-mode semifancy -trim-ad-domain -newline -jobs $(jobs -p | wc -l))" # Uncomment the following line to automatically clear errors after showing # them once. This not only clears the error for powerline-go, but also for # everything else you run in that shell. Don't enable this if you're not # sure this is what you want. #set "?" } if [ "$TERM" != "linux" ] && [ -f "/usr/bin/powerline-go" ]; then PROMPT_COMMAND="_update_ps1; $PROMPT_COMMAND" fi
-
編譯
+關注
關注
0文章
659瀏覽量
32913 -
Tina
+關注
關注
2文章
45瀏覽量
16995 -
RISC-V
+關注
關注
45文章
2300瀏覽量
46257 -
Docker
+關注
關注
0文章
478瀏覽量
11876
發布評論請先 登錄
相關推薦
評論