Dockerfile
Dockerfile
基本结构
Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 快速创建自定义镜像。
Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。
Docker分为四部分:
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时默认要执行的指令
其中,一开始必指明所基于的镜像名称,接下来一般会说明维护者信息。
后面则是镜像操作指令,例如RUN指令,RUN指令将对镜像执行跟随的命令。每运行一条RUN指令,镜像添加新的一层,并提交。
最后是CMD指令来指定运行容器时的操作指令。
指令
FROM
格式为FROM <image>
或FROM <image>:<tag>
。
第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)。
# 第一行必须指定基于的基础镜像
FROM centos
LABEL MAINTAINER
格式为LABEL MAINTAINER <name email_address>
,指定维护者信息
# 维护者信息
LABEL MAINTAINER "daxinyu 3171344634@qq.com"
RUN
格式为RUN <command>
或RUN ["executable","param1","param2"]
。
前者将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行。指定使用其他终端可以通过第二种方式实现,例如:
RUN ["/bin/bash","-c","echo hello"]
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行,例如:
RUN echo "hello world\nhello tom" > /tmp/abc && \
cat /tmp/abc
# 镜像操作指令
RUN rm -rf /etc/yum.repos.d/* && \
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo && \
yum -y install make gcc gcc-c++ openssl-devel pcre-devel expat-devel libtool libxml2-devel && \
useradd -r -M -s /sbin/nologin apache && \
cd /usr/src/apr-${apr_version} && \
sed -i '/$RM "$cfgfile"/d' configure && \
./configure --prefix=/usr/local/apr && make && make install && \
cd /usr/src/apr-util-${apr_util_version} && \
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr && \
make && make install && \
cd /usr/src/httpd-${httpd_version} && \
./configure --prefix=/usr/local/apache \
--sysconfdir=/etc/httpd24 \
--enable-so \
--enable-ssl \
--enable-cgi \
--enable-rewrite \
--with-zlib \
--with-pcre \
--with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util/ \
--enable-modules=most \
--enable-mpms-shared=all \
--with-mpm=prefork && make && make install && \
sed -i '/#ServerName/s/#//g' /etc/httpd24/httpd.conf
CMD
CMD支持三种格式:
CMD ["executable","param1","param2"]
使用exec执行,推荐方式CMD command param1 param2
在/bin/sh中执行,提供给需要交互的应用CMD ["param1","param2"]
提供给ENTRYPOINT的默认参数
CMD用于指定启动容器时默认要执行的命令,每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令。
# 容器启动时默认要执行的指令
CMD ["-D","FOREGROUND"]
EXPOSE
格式为EXPOSE <port> [<port>...]
。
EXPOSE用于告诉Docker服务器容器暴露的端口号,供互联系统使用。
在启动容器时通过-P,Docker主机会自动分配一个端口转发到指定的端口;
使用-p则可以具体指定哪个本地端口映射过来。
EXPOSE 80
ENV
格式为ENV <key> <value>
。指定一个环境变量,会被后续RUN指令使用,并在容器运行时保持。例如:
ENV apr_version=1.7.0 apr_util_version=1.6.1 httpd_version=2.4.54
ADD
格式为ADD <src> <dest>
。
该命令将复制指定的
ADD files/* /usr/src/
COPY
格式为COPY <src> <dest>
。
复制本地主机的
当使用本地目录为源目录时,推荐使用COPY。
COPY files /tmp/
ENTRYPOINT
ENTRYPOINT有两种格式:
- ENTRYPOINT ["executable","param1","param2"]
- ENTRYPOINT command param1 param2(在shell中执行)
配置容器启动后执行的命令,并且不可被docker run提供的参数覆盖。而且,如果在docker run的后面提供了参数,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。
每个Dockerfile中只能有一个ENTRYPOINT,当指定多个ENTRYPOINT时,只有最后一个生效。
ENTRYPOINT /usr/local/apache/bin/apachectl -DFOREGROUND
VOLUME
格式为VOLUME ["/data"]
。
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
VOLUME /data
USER
格式为USER daemon
。
指定运行容器时的用户名或UID,后续的RUN也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:
RUN groupadd -r postgres && useradd -r -g postgres postgres
要临时获取管理员权限可以使用gosu,而不推荐sudo。如果不指定,容器默认是root运行。
WORKDIR
格式为WORKDIR /path/to/workdir
。
为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。
可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为/a/b/c。
WORKDIR /usr/local/apache
ONBUILD
格式为ONBUILD [INSTRUCTION]
。
配置当所创建的镜像作为其他镜像的基础镜像时,所执行的操作指令。
例如,Dockerfile使用如下的内容创建了镜像image-A
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
此时,如果基于image-A创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像时,会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令。
FROM image-A
# Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src
使用ONBUILD指令的镜像,推荐在标签中注明,例如ruby:1.9-onbuild。
创建镜像
编写完成Dockerfile后,可以通过docker build命令来创建镜像。
基本的格式为docker build [选项] 路径
,该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下所有内容发送给Docker服务端,由服务端来创建镜像。因此一般建议放置Dockerfile的目录为空目录。
另外,可以通过 .dockerignore
文件(每一行添加一条匹配模式)来让Docker忽略路径下的目录和文件。
要指定镜像的标签信息,可以通过-t选项。
podman进行dockerfile做一个httpd编译安装的镜像
创建一个目录存放dockerfile和下载的包
[root@localhost ~]# mkdir httpd
[root@localhost ~]# ls
anaconda-ks.cfg httpd
[root@localhost ~]# cd httpd/
[root@localhost httpd]# touch Dockerfile
[root@localhost httpd]# mkdir files
[root@localhost httpd]# cd files/
[root@localhost files]# wget http://mirrors.aliyun.com/apache/apr/apr-1.7.0.tar.gz https://mirrors.aliyun.com/apache/apr/apr-util-1.6.1.tar.gz https://mirrors.aliyun.com/apache/httpd/httpd-2.4.54.tar.gz
[root@localhost files]# ls
apr-1.7.0.tar.gz apr-util-1.6.1.tar.gz httpd-2.4.54.tar.gz
[root@localhost files]# cd
[root@localhost ~]#
编写dockerfile和脚本文件
[root@localhost ~]# cd httpd/
[root@localhost httpd]# cd files/
[root@localhost files]# vim entrypoint.sh
[root@localhost files]# chmod -x entrypoint.sh
[root@localhost files]# cd ..
[root@localhost httpd]# vim Dockerfile
[root@localhost httpd]# cat Dockerfile
FROM centos
LABEL MAINTAINER "daxinyu 3171344634@qq.com"
ENV apr_version=1.7.0 apr_util_version=1.6.1 httpd_version=2.4.54
ADD files/* /usr/src/
ADD files/entrypoint.sh /
RUN rm -rf /etc/yum.repos.d/* && \
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo && \
yum -y install make gcc gcc-c++ openssl-devel pcre-devel expat-devel libtool libxml2-devel && \
useradd -r -M -s /sbin/nologin apache && \
cd /usr/src/apr-${apr_version} && \
sed -i '/$RM "$cfgfile"/d' configure && \
./configure --prefix=/usr/local/apr && make && make install && \
cd /usr/src/apr-util-${apr_util_version} && \
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr && \
make && make install && \
cd /usr/src/httpd-${httpd_version} && \
./configure --prefix=/usr/local/apache \
--sysconfdir=/etc/httpd24 \
--enable-so \
--enable-ssl \
--enable-cgi \
--enable-rewrite \
--with-zlib \
--with-pcre \
--with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util/ \
--enable-modules=most \
--enable-mpms-shared=all \
--with-mpm=prefork && make && make install && \
sed -i '/#ServerName/s/#//g' /etc/httpd24/httpd.conf && \
yum clean all && \
yum -y remove gcc gcc-c++ make && \
rm -rf /tmp/* /usr/src/*
WORKDIR /usr/local/apache
EXPOSE 80
CMD ["/usr/local/apache/bin/httpd","-D","FOREGROUND"]
ENTRYPOINT ["/bin/bash","/entrypoint.sh"]
#编写脚本文件
[root@localhost httpd]# ls
Dockerfile files
[root@localhost httpd]# cd files/
[root@localhost files]# ls
apr-1.7.0.tar.gz apr-util-1.6.1.tar.gz entrypoint.sh httpd-2.4.54.tar.gz
[root@localhost files]# cat entrypoint.sh
#!/bin/bash
sed -i '/^#ServerName/s/#//g' /usr/local/apache/conf/httpd.conf
exec "$@"
[root@localhost files]# chmod +x entrypoint.sh
使用dockerfile创建镜像
[root@localhost ~]# podman build -t a3171344634/httpd:v2.0 httpd/
将镜像上传
[root@localhost ~]# podman login
Username: a3171344634
Password:
Login Succeeded!
[root@localhost ~]# podman push a3171344634/httpd:v2.0
Getting image source signatures
Copying blob ebf089b6f3b9 done
Copying blob 7bc2c77c64b4 done
Copying blob 2653d992f4ef done
Copying config 3bc9ba7b2a done
Writing manifest to image destination
Storing signatures
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)