前陣子在玩 Dockerfile 想做成自動化打包 + 測試,在這過程中深刻體認到... Docker 需要注意的地方真不少,三天時間每當打包好後的 10 到 20分鐘,就可以找到數個問題,後續的我就浮沉在尋找問題跟解決問題之間。整理這篇文章作為經驗分享期許能幫助到更多人。
什麼是 Dockerfile
在開始講會碰到的一些問題前,要先知道 Dockerfile 其實是一個檔案用於撰寫 Docker Image 的建置腳本,編寫好後使用
Docker build -t {repository name} .
指令,這時 Docker 就會為我們打造一個專屬於自己的 Docker Image。
接著可以再執行
docker run -it {repository name}
,運行起一個被稱之為 Container 的環境,在環境中有一個與本機隔絕獨立的環境,至於這樣有什麼好處小編不在此多講,試想一個輕量化可通過指令控制的 VM 能帶來哪些好處,那大致也不會差得太遠了。認識 Dockerfile
既然知道是一種腳本那就會有語法,讓我們用一個範例來認識 Dockerfile
範例
這是一個期望用於測試環境用的腳本,所以主要包含 Java, HBase, Maven 和 Proguard 等。(除此之外還包含 SSh 是由於 HBase 會通過通過此工具連線自身喚起服務)
Dockerfile
FROM centos:centos6.10
MAINTAINER CookieTsai
# Add JDK, HBase and Maven tarball file, using ADD will auto unzip the file.
ADD jdk1.7.0_151.tar.gz /opt/
ADD apache-maven-3.5.4-bin.tar.gz proguard5.3.3.tar.gz /opt/
ADD hbase-1.2.9-local.tar.gz /opt/
# 1. Install sshd and vim and making ssh non-ask
# 2. Setting ssh login without password and close firewall
# 3. Install JDK, HBase and Maven
RUN yum -y install openssh* vim-enhanced \
&& echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config \
&& ssh-keygen -t rsa -f ~/.ssh/id_rsa -P "" \
&& cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys \
&& chmod 600 ~/.ssh/authorized_keys \
&& service iptables stop && chkconfig iptables off \
&& ln -s /opt/jdk1.7.0_151 /opt/java \
&& ln -s /opt/apache-maven-3.5.4 /opt/maven \
&& ln -s /opt/proguard5.3.3 /opt/proguard \
&& ln -s /opt/hbase-1.2.9 /opt/hbase
ENV USER=root \
JAVA_HOME=/opt/java \
MAVEN_HOME=/opt/maven \
HBASE_HOME=/opt/hbase \
PROGUARD_HOME=/opt/proguard \
PATH=/opt/proguard/bin:/opt/hbase/bin:/opt/maven/bin:/opt/java/bin:$PATH
# 1. Install nodejs's nvm
# 2. Using npm install newman and newman-reporter-html
RUN curl -s -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash \
&& source /root/.nvm/nvm.sh \
&& nvm install v10.14.2 \
&& nvm alias default v10.14.2 \
&& nvm use default \
&& npm install -g newman \
&& npm install -g newman-reporter-html
EXPOSE 22 2181 8090 60000 60010 60020 60030
# Set root's setting
ADD startup.sh /startup.sh
RUN cat /startup.sh >> /root/.bashrc && echo "root:root" | chpasswd
CMD ["/bin/bash"]
startup.sh
if [ -d "$HBASE_HOME" ]; then
# Start SSH Server
service sshd start
# Set Reginservers
HOST_NAME=`hostname`
sed -i "s/localhost/$HOST_NAME/" /opt/hbase/conf/hbase-site.xml
echo $HOST_NAME > /opt/hbase/conf/regionservers
# Start HBase
start-hbase.sh
fi
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion" # This loads nvm bash_completion
語法解析
- FROM:指要以哪一個 Image 作為基底
- MAINTAINER:註明主要的維護者
- ADD:將指定路徑的目錄或檔案放入 Image 的指定目錄中
- RUN:建置時會執行此指令後的語法
- ENV:設定系統內的環境變數
- EXPOSE:設定給使用者知道哪些 PORT 有開放
- CMD:設定當啟動時預設執行的命令
註解
- 多數語法指令是相互獨立,建議使用絕對路徑或直接宣告
ADD /opt/sample.tar.gz /opt RUN cd /opt RUN tar -zxvf sample.tar.gz # 與前一指令相互獨立,此執行結果為找不到檔案
- 每一個指令 (如:RUN、ADD) 執行後會有一次 Commit
ADD
指令在指定壓縮檔案加入時,如果有支援的情況下會自動解壓縮- 除非確定要解壓縮其他時候都可以利用
COPY
指令取代來ADD
其他
- Docker Image 最多只能有 127 個 Parents
- 使用
docker run
時並非是真的使用 root 身份完成登入必須當心 - 使用
docker run -it {image name}
時是可以利用.bashrc
執行預設指令