1.FROM : 尽量使用官方的image作为base image。
FROM scrach
FROM centos
FROM ubuntu:14.04
2.LABEL : Metadata不可少。
LABEL maintainer="hurricane@139.com"
LABEL version="1.0"
LABEL description="This is description"
3.RUN : 每运行一次RUN都会在image上产生新的一层,因此避免无用分层,合并多条命令为一行,为了美观,复杂的语句请用反斜线换行。
RUN yum update && yum intall -y \ #反斜杠换行
vim python-dev
RUN apt-get update && apt-get intall -y perl \
pwgen --no-install-recommends && rm -rf \
/var/lib/apt/list/* #注意清理cache
RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
4.WORKDIR : 用于设定当前工作目录,不要使用RUN cd(这样也能实现WORKDIR的功能,但不推荐),尽量使用绝对目录。
WORKDIR /test #如果没有会自动创建test目录
WORKDIR demo
RUN pwd #输出结果应该是/test/demo
5.ADD and COPY : 把本地文件添加到image里,ADD不止可以添加文件而且可以解压缩,大部分情况,COPY优于ADD,添加远程文件/目录请使用curl或者wget。
ADD hello /
ADD test.tar.gz / #添加到根目录并解压
COPY hello /test
6.ENV : 设置常量,尽量使用ENV增加可维护性。
ENV MYSQL_VERSION 5.6 #设置常量
RUN apt-get install -y mysql-server="${MYSQL_VERSION}"\
&& rm-rf /var/lib/apt/list/* #引用常量
7.CMD:
i.容器启动时默认执行的命令;
ii.如果docker run指定了其他命令,CMD命令被忽略:
FROM centos
ENV name docker
CMD echo "hello $name"
通过docker run [image] #输出hello docker
通过docker run -it [image] /bin/bash #不会输出
iii.如果定义了多个CMD,只有最后一个会执行。
8.ENTRYPOINT:
i.让容器以应用程序或者服务的形式运行;
ii.不会被忽略,一定会执行;
iii.最佳实践:写一个shell脚本作为entrypoint:
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
9.RUN 和 CMD 和 ENTRYPOINT执行的命令有两种格式,一种Shell格式,一种Exec格式:
Shell格式:
RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"
Exec格式:
RUN ["apt-get","install","-y","vim"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/echo","hello docker"]
Shell格式与Exec格式的区别:
Dockerfile1
FROM centos
ENV name docker
ENTRYPOINT echo "hello $name"
=> hello docker
Dockerfile2
FROM centos
ENV name docker
ENTRYPOINT ["/bin/echo","hello $name"]
=> hello $name
Shell格式可以使用常量,Exec格式无法使用
为了让Exec格式识别常量,需要将Dockerfile2改为:
FROM centos
ENV name docker
ENTRYPOINT ["/bin/bash","-c"," echo hello $name"]
10.VOLUME 暴露文件的存储:
VOLUME ["/var/lib/mysql"]
docker run -v mysql:/var/lib/mysql
11.EXPOSE 暴露docker的container端口:
EXPOSE 8080
docker run -p 80:8080 #容器的8080端口映射到宿主机的80端口
12.实战:
i.新建app.py文件:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "hello docker"
if __name__ == '__main__'
app.run()
ii.Dockerfile如下:
FROM python:2.7
LABEL maintainer="Li hurricane@139.com"
RUN pip install flask
COPY app.py /app/
WORKDIR /app
EXPOSE 5000
CMD["python","app.py"]
iii.构建镜像与执行:
docker build -t hurricane123/python-hello .
docker run -d hurricane123/python-hello
参考:
视频教程:系统学习Docker 践行DevOps理念