原文鏈接:http://wyb0.com/posts/docker-dockerfile/
操作系統(tǒng):Ubuntu14.04.1
Docker版本:Docker version 17.06.0-ce, build 02c1d87
0x00 Dockerfile
Dockerfile里面其實是一條條的指令,Docker會把Dockerfile的指令翻譯為linux命令睛廊,
每一條指令都會創(chuàng)建一個鏡像届榄,下一條指令將在這個鏡像的基礎(chǔ)上進行修改操作后再生成一個鏡像。
讓你可以對下載好的鏡像進行一些操作(比如安裝軟件秦效、向鏡像復(fù)制文件等),從而構(gòu)造定制化的鏡像涎嚼。
0x01 Dockerfile基本指令
FROM <image name>:指定新的鏡像基于什么創(chuàng)建(可以嘗試使用alpine:latest和debian:jessie)
MAINTAINER <author name>:設(shè)置該鏡像的作者
COPY <source> <dest>:復(fù)制文件阱州,dest要以 / 結(jié)尾
WORKDIR /path/to/workdir:相當(dāng)于切換目錄,對RUN法梯、CMD苔货、和ENTRYPOINT生效
RUN <command>:在shell執(zhí)行命令
EXPOSE port1 port2:容器運行時監(jiān)聽的端口
CMD:容器默認的執(zhí)行命令,Dockerfile只允許使用一次CMD命令(使用數(shù)組)
ENTRYPOINT:類似于CMD立哑,Dockerfile只允許使用一次(使用數(shù)組)
ENV <key> <value>:設(shè)置環(huán)境變量
USER <uid>:鏡像正在運行時設(shè)置一個uid夜惭,即設(shè)定啟動容器的用戶,默認為root
VOLUME ['/data']:授權(quán)訪問從容器內(nèi)到主機的目錄
CMD與ENTRYPOINT的區(qū)別:
#docker run ubuntu:test會執(zhí)行/bin/echo 'this is test'
CMD ['/bin/echo','this is test']
#docker run ubuntu:test會執(zhí)行/bin/echo 'entrypoint test'铛绰,會輸出'entrypoint test'
ENTRYPOINT ['/bin/echo','entrypoint test']
#docker run ubuntu:test start即執(zhí)行/etc/init.d/mysql start诈茧,CMD中的默認參數(shù)會被覆蓋
ENTRYPOINT ['/etc/init.d/mysql']
CMD ["restart"]#CMD中的值會作為ENTRYPOINT的默認參數(shù)
0x02 實例
- Dockerfile
reber@wyb:~/range$ cat Dockerfile
FROM ubuntu:14.04
MAINTAINER reber
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
COPY src/sources.list /etc/apt/sources.list
RUN apt-get update && apt-get upgrade -y
COPY src/range.zip /tmp/
COPY src/privileges.sql /tmp/
RUN apt-get install -y apache2 mysql-server mysql-client php5 php5-gd php5-mysql libapache2-mod-php5 libapache2-mod-auth-mysql unzip && apt-get clean
WORKDIR /var/www/html
RUN set -x \
&& unzip -x /tmp/range.zip -d ./ \
&& chmod 777 ./range/upload/uploads \
&& chmod 777 ./range/xss_platform/upload
EXPOSE 80
COPY src/start.sh /start.sh
RUN chmod +x /start.sh
ENTRYPOINT ["/start.sh"]
CMD ["--help"]
- src/privileges.sql
reber@wyb:~/range$ cat src/privileges.sql
use mysql;
UPDATE user SET password=PASSWORD('root') where USER='root';
FLUSH PRIVILEGES;
- src/sources.list
reber@wyb:~/range$ cat src/sources.list
deb http://debian.ustc.edu.cn/ubuntu/ trusty main restricted universe multiverse
deb http://debian.ustc.edu.cn/ubuntu/ trusty-security main restricted universe multiverse
deb http://debian.ustc.edu.cn/ubuntu/ trusty-updates main restricted universe multiverse
deb http://debian.ustc.edu.cn/ubuntu/ trusty-proposed main restricted universe multiverse
deb http://debian.ustc.edu.cn/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ trusty main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://debian.ustc.edu.cn/ubuntu/ trusty-backports main restricted universe multiverse
- src/start.sh
reber@wyb:~/range$ cat src/start.sh
#!/bin/bash
set -x
echo 'start mysql'
/etc/init.d/mysql start
sleep 3
echo 'import rtest.sql'
mysql < /var/www/html/range/rtest.sql
sleep 3
echo 'set password'
mysql < /tmp/privileges.sql
/etc/init.d/mysql restart
/etc/init.d/apache2 restart
echo 'set success'
/usr/bin/tail -f /dev/null
0x03 構(gòu)建鏡像
reber@wyb:~/range$ ls
Dockerfile src
reber@wyb:~/range$ ls src
range.zip sources.list start.sh
#構(gòu)建鏡像
reber@wyb:~/range$ docker build -t range:1.0 .
#運行容器,并將容器的80端口轉(zhuǎn)到宿主機的8888端口
reber@wyb:~/range$ docker run -itd -p 8888:80 range:v1.0
0x04 注意事項
- 使用緩存
因為每條指令都會創(chuàng)建一個鏡像捂掰,若一個鏡像已經(jīng)存在的話則不會重新執(zhí)行指令創(chuàng)建新鏡像敢会,而是直接使用镊叁。
為有效的利用已存在的鏡像,應(yīng)保持Dockerfile的一致性走触,盡量在末尾修改晦譬,比如說前幾行都如下設(shè)置:
FROM ubuntu:14.04
MAINTAINER reber <1070018473@qq.com>
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sourse.list
RUN apt-get update
RUN apt-get upgrade -y #盡量不要upgrade
- 使用標簽
始終使用-t參數(shù)給鏡像打標簽:docker build -t ubuntu:range1 .
- 公開端口
Docker鏡像應(yīng)該能在任何主機上運行,所以不要通過Dockerfile映射共有端口互广,只映射私有端口:EXPOSE 80
- CMD與ENTRYPOINT
應(yīng)該使用數(shù)組語法敛腌,兩者可以結(jié)合使用
ENTRYPOINT ["/start.sh"] #docker run的參數(shù)將傳遞給start.sh
CMD ["--help"] #若沒有參數(shù)傳遞則顯示幫助文檔