Dockerfile是用于构建docker镜像的脚本文件,通过编写脚本,可以实现自定义镜像。
Dockerfile关键字
FROM
基础镜像,Dockerfile第一条指令必须是FROM。
例如,下列就表示使用ubuntu的最新版本最为基础镜像。
FROM ubuntu:latest
MAINTAINER
镜像作者,例如:
MAINTAINER [email protected]
LABEL
LABEL
为镜像增加元数据,一个LABEL
是键值对,多个键值对之间使用空格分开,命令换行时是使用反斜杠\
。
建议使用LABEL指令替换MAINTAINER指令,例如:
LABEL author="lixingwu"
LABEL email="[email protected]"
LABEL version="1.0"
LABEL description="This is my Dockerfile."
添加后可使用 docker inspect
指令查看到添加的信息。
RUN
构建容器时运行的shell脚本。
# 运行安装net-tools命令
RUN yum install net-tools
每一行RUN指令会生成一层Layer,所以尽量减少使用使用RUN指令,可以用&&
把多个命令写在同一个RUN指令中,以减少Layer的层数。例如:
RUN apt-get update && \
apt-get install -y wget && \
mkdir /home/temp && \
cd /home/temp && \
touch readme.md
EXPOSE
声明对外暴露的端口,只起到声明作用,告诉使用者,运行该镜像可以映射的端口。只有在使用-p
指令映射端口后才能通过端口访问到镜像。
例如,nginx镜像提供80和443端口,就可以在dockerfile文件中使用如下命令声明:
EXPOSE 80
EXPOSE 443
WORKDIR
在进入容器时,默认的目录,起到落脚点的作用。例如:
WORKDIR /home
此时,在进入启动容器后,就会自动定位到指定的目录/home
,主要用于快速定位到目标目录。假设是nginx容器,我们希望进入容器后就直接定位到nginx所在的目录,而不是让我们手动切换过去。
USER
指定镜像运行时的用户,通常情况下,为了保证容器的安全性,我们都不会使用直接使用容器里面的root用户。
因为root用户权限太高
,容易访问系统文件,失误修改到关键文件,容易导致容器崩溃
。
我们通常会为容器创建一个非root的用户,然后赋予我们工作目录的操作权限,保证该用户只会操作我们允许操作的目录和文件。
在使用USER
指令时,我们需要先保证该用已经存在,如果不存在,可以手动创建用户:
RUN useradd -m -d /home/nginx -s /bin/sh -f -1 -c "this is a nginx" nginx
USER nginx
在构建完成后,我们进入容器,登录的用户就是设置的nginx
用户。
docker build -t mynginx:0.0.1 .
docker run -it mynginx:0.0.1
# 使用whoami可查看当前登录用户,
# 因为我们在Dockerfile中使用USER指令指定了,所以登录后就是我们指定的用户
nginx@cd4ee8b6a39a:/$ whoami
nginx
ENV
容器运行时环境变量。
# 定义项目根目录
ENV WORK_PAYH /usr/work
# 使用环境变量
WORKDIR $WORK_PAYH
这些定义的环境变量可在运行时被覆盖,比如,我们在dockerfile文件中定义环境变量。
ENV BASE_URL lhttp://ocalhost:8888
然后我们在启动时覆盖掉,容器里的环境变量就会被覆盖
。
docker run -it -e BASE_URL=http://localhost:9999 mynginx:0.0.2
# 在容器中输出BASE_URL环境变量,已被覆盖
nginx@1fe788f36758:/$ echo $BASE_URL
http://localhost:9999
ADD
把宿主机下的文件拷贝到容器,如果是tar压缩包会自动解压
,url会自动下载
;
# 把文件 myhostconfig.conf ,加入到容器 /home/nginx/ 目录下
ADD myhostconfig.conf /home/nginx/
# 把文件 myhostconfig.conf ,加入到容器 /home/nginx/ 目录下,并重新命名为 my.conf
ADD myhostconfig.conf /home/nginx/my.conf
# 把 app.tar.gz 解压到容器 /home/app/ 目录下
ADD app.tar.gz /home/app/
# 把网络资源下载到 /home/java/ 目录下
ADD https://files.cnblogs.com/files/lixingwu/app.tar.gz /home/app1/
# 把当前目录所有文件拷贝到容器/home/temp/目录下
ADD . /home/temp/
# 把当前目录下的txt文件,复制到容器/home/txt/目录下
ADD *.txt /home/txt/
# 把文件夹data下的内容拷贝到到/home/mydata/目录下,拷贝的文件不能有反斜杠
ADD data /home/mydata/
# 如果需要复制文件夹,把目标目录也设置为同名文件夹即可
ADD data /home/data/
注意:
-
下载网络资源的压缩包不会自动解压,而且还会使镜像
文件变大
,如果需要解压网络资源,可以使用RUN指令下载、解压、删除操作。 -
在复制全部文件时,如果需要忽略其中的一些文件,可以定义
.dockerignore
文件进行排除,.dockerignore语法和.gitignore
语法一致。 -
文件名尽量不要出现
中文
,不然复制时会被转码。 -
指令只拷贝目录中的内容而
不包含目录自身
。
COPY
把宿主机下的文件,原封不同的复制到镜像容器下。该指令只能复制本地的文件,而且也不会自动解压压缩包。大多数情况都是使用copy指令,只有需要自动下解压和自动下载url时才需要add指令。
copy指令的规则和add指令一致,复制本地文件、文件夹可平替,而且copy语义
上也更符合我们的操作。
COPY app.tar.gz /home/copy/app/
COPY . /home/copy/temp/
COPY *.txt /home/copy/txt/
COPY data /home/copy/mydata/
COPY data /home/copy/data/
VOLUME
挂载容器卷,持久化数据库到宿主机,效果和-v
一样。
例如:需把主机的/tmp/nginx
挂在到容器的/tmp
就可以写成
VOLUME ["/tmp/nginx","/tmp"]
CMD
用于指定默认的容器主进程启动命令。
可以使用 shell 脚本的方式,例如:CMD java -jar app.jar
也可以使用exec的方式:例如:CMD["java", "-jar", "app.jar"]
cmd指令只能写一个,存在多个只有最后一个生效。
如果在run时加入参数,CMD指令会被覆盖,例如:
docker run -it -p 8080:8080 tomcat /bin/bash
此时,/bin/bash
参数会把CMD指令覆盖,会导致app没有启动起来。
ENTRYPOINT
用于指定默认的容器主进程启动命令,不会被run时加入参数覆盖,会把参数传递给ENTRYPOINT
指令。
例如:ENTRYPOINT["java", "-jar", "app.jar"]
,在启动时传入参数:
docker run -it -p 8080:8080 tomcat --spring.profiles.active=test
此时,启动参数就会变成:
java -jar app.jar --spring.profiles.active=test
构建镜像
使用build
执行构建脚本,命令最后的一个点是表示构建市时的上下文,点表示在执行命令的当前目录。
在构建时,docker会在上下文中找到Dockerfile
文件,然后根据文件编写的脚本镜像镜像构建,其中imagename
表示镜像的名字,tag
表示镜像的版本,镜像名字可用重复,但是标签不可以,如果出现同名同标签时会覆盖存在的镜像文件。
docker build -t [imagename]:[tag] .
标签:容器,nginx,app,关键字,指令,镜像,home,Dockerfile
From: https://www.cnblogs.com/lixingwu/p/16759754.html