首页 > 系统相关 >docker的dockerfile案例nginx学习

docker的dockerfile案例nginx学习

时间:2022-12-22 22:32:53浏览次数:60  
标签:get -- apt nginx && docker dockerfile

一、什么是Dockerfile

Dockerfile是自动构建docker镜像的配置文件,将镜像构建过程通过指令的方式定义在Dockerfile中。配合​​docker build​​命令行可以实现自动化的Docker镜像的构建。

二、看官方​​https://hub.docker.com/_/nginx/​​的nginx案例dockerfile,版本为nginx1.23.3

FROM debian:bullseye-slim
LABEL maintainer="NGINX Docker Maintainers <[email protected]>"
ENV NGINX_VERSION 1.23.3

ENV NJS_VERSION 0.7.9

ENV PKG_RELEASE 1~bullseye
RUN set -x \
# create nginx user/group first, to be consistent throughout docker variants
&& addgroup --system --gid 101 nginx \
&& adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid 101 nginx \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y gnupg1 ca-certificates \
&& \
NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \
found=''; \
for server in \
hkp://keyserver.ubuntu.com:80 \
pgp.mit.edu \
; do \
echo "Fetching GPG key $NGINX_GPGKEY from $server"; \
apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \
done; \
test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \
apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/* \
&& dpkgArch="$(dpkg --print-architecture)" \
&& nginxPackages=" \
nginx=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-xslt=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-geoip=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-image-filter=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${PKG_RELEASE} \
" \
&& case "$dpkgArch" in \
amd64|arm64) \
# arches officialy built by upstream
echo "deb https://nginx.org/packages/mainline/debian/ bullseye nginx" >> /etc/apt/sources.list.d/nginx.list \
&& apt-get update \
;; \
*) \
# we're on an architecture upstream doesn't officially build for
# let's build binaries from the published source packages
echo "deb-src https://nginx.org/packages/mainline/debian/ bullseye nginx" >> /etc/apt/sources.list.d/nginx.list \
\
# new directory for storing sources and .deb files
&& tempDir="$(mktemp -d)" \
&& chmod 777 "$tempDir" \
# (777 to ensure APT's "_apt" user can access it too)
\
# save list of currently-installed packages so build dependencies can be cleanly removed later
&& savedAptMark="$(apt-mark showmanual)" \
\
# build .deb files from upstream's source packages (which are verified by apt-get)
&& apt-get update \
&& apt-get build-dep -y $nginxPackages \
&& ( \
cd "$tempDir" \
&& DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)" \
apt-get source --compile $nginxPackages \
) \
# we don't remove APT lists here because they get re-downloaded and removed later
\
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
# (which is done after we install the built packages so we don't have to redownload any overlapping dependencies)
&& apt-mark showmanual | xargs apt-mark auto > /dev/null \
&& { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \
\
# create a temporary local APT repo to install from (so that dependency resolution can be handled by APT, as it should be)
&& ls -lAFh "$tempDir" \
&& ( cd "$tempDir" && dpkg-scanpackages . > Packages ) \
&& grep '^Package: ' "$tempDir/Packages" \
&& echo "deb [ trusted=yes ] file://$tempDir ./" > /etc/apt/sources.list.d/temp.list \
# work around the following APT issue by using "Acquire::GzipIndexes=false" (overriding "/etc/apt/apt.conf.d/docker-gzip-indexes")
# Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied)
# ...
# E: Failed to fetch store:/var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied)
&& apt-get -o Acquire::GzipIndexes=false update \
;; \
esac \
\
&& apt-get install --no-install-recommends --no-install-suggests -y \
$nginxPackages \
gettext-base \
curl \
&& apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list \
\
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
apt-get purge -y --auto-remove \
&& rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list; \
fi \
# forward request and error logs to docker log collector
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
# create a docker-entrypoint.d directory
&& mkdir /docker-entrypoint.d

COPY docker-entrypoint.sh /
COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d
COPY 20-envsubst-on-templates.sh /docker-entrypoint.d
COPY 30-tune-worker-processes.sh /docker-entrypoint.d
ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 80

STOPSIGNAL SIGQUIT

CMD ["nginx", "-g", "daemon off;"]

三、解析nginx的Dockerfile语法

FROM
FROM debian:bullseye-slim
一般我们构建镜像的都需要一个基础的linux操作系统的发行版镜像,并且在此基础上我们构建自己的镜像。

FROM指令的作用就是指定基础镜像,nginx这里使用的基础linux镜像是debian:bullseye-slim。其中debian:bullseye是debian的linux发行本操作系统的一个版本,版本名称叫做bullseye。slim通常是指这个镜像是该发行版本中的最小安装版本,因为我们构建完成的镜像是要在后续的持续集成过程中,以及仓库和docker服务器之间网络传播的,所以尽可能让镜像的构建结果size最小化。基础镜像的选择要着重考虑size的大小,满足linux基本功能及你的程序运行的前提下越小越好。

LABEL

LABEL用于给当前镜像添加一些描述、解释性信息,如:当前镜像的维护人及联系方式等信息。用键值对的方式自定义,一行可以定义多个。

案例:LABEL maintainer="NGINX Docker Maintainers <​​[email protected]​​>"

LABEL的语法

LABEL <key>=<value> <key>=<value> <key>=<value> ...

也可以定义多行,如maintainer维护人信息,description镜像描述信息。如果描述信息一行写不下,可以用“\”换行。Dockerfile语法中有一个指令叫做MAINTAINER,专门用于描述该镜像的维护人信息,但是现在已经不建议使用了,统一使用LABEL。

​LABEL maintainer="NGINX Docker Maintainers "

#多行用\作为换行

LABEL description="This is a Docker image \

for nginx 1.23.3. "

ENV

ENV的作用是设置环境变量,该环境变量设置之后,可以在构建过程及容器运行时的shell脚本中使用该变量,使用方法如:${NGINX_VERSION}。学过JAVA的同学想想你的JAVA_HOME环境变量怎么设置的以及怎么使用的?ENV是同样的道理。只不过放到docker这里语法发生了变化而已,语法格式:ENV 环境变量KEY 环境变量Value。

ENV NGINX_VERSION   1.23.3
ENV NJS_VERSION 0.7.9
ENV PKG_RELEASE 1~bullseye
RUN

RUN指令的作用就是执行linux的shell脚本,通过下图可以看到在shell脚本中可以使用通过ENV定义的环境变量。

RUN set -x \

# create nginx user/group first, to be consistent throughout docker variants
&& addgroup --system --gid 101 nginx \
&& adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid 101 nginx \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y gnupg1 ca-certificates \
&& \
NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \
found=''; \
for server in \
hkp://keyserver.ubuntu.com:80 \
pgp.mit.edu \
; do \
echo "Fetching GPG key $NGINX_GPGKEY from $server"; \
apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \
done; \
test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \
apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/* \
&& dpkgArch="$(dpkg --print-architecture)" \
&& nginxPackages=" \
nginx=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-xslt=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-geoip=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-image-filter=${NGINX_VERSION}-${PKG_RELEASE} \
nginx-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${PKG_RELEASE} \
" \
&& case "$dpkgArch" in \
amd64|arm64) \
echo "deb https://nginx.org/packages/mainline/debian/ bullseye nginx" >> /etc/apt/sources.list.d/nginx.list \
&& apt-get update \
;; \
*) \
echo "deb-src https://nginx.org/packages/mainline/debian/ bullseye nginx" >> /etc/apt/sources.list.d/nginx.list \
&& tempDir="$(mktemp -d)" \
&& chmod 777 "$tempDir" \
&& savedAptMark="$(apt-mark showmanual)" \
&& apt-get update \
&& apt-get build-dep -y $nginxPackages \
&& ( \
cd "$tempDir" \
&& DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)" \
apt-get source --compile $nginxPackages \
) \
&& apt-mark showmanual | xargs apt-mark auto > /dev/null \
&& { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \
\
&& ls -lAFh "$tempDir" \
&& ( cd "$tempDir" && dpkg-scanpackages . > Packages ) \
&& grep '^Package: ' "$tempDir/Packages" \
&& echo "deb [ trusted=yes ] file://$tempDir ./" > /etc/apt/sources.list.d/temp.list \
&& apt-get -o Acquire::GzipIndexes=false update \
;; \
esac \
&& apt-get install --no-install-recommends --no-install-suggests -y \
$nginxPackages \
gettext-base \
curl \
&& apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list \
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
&& if [ -n "$tempDir" ]; then \
apt-get purge -y --auto-remove \
&& rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list; \
fi \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& mkdir /docker-entrypoint.d

对于nginx镜像而言,RUN指令的作用就是执行一系列shell命令行(脚本)来完成nginx的安装。所以说要想掌握RUN指令的重点不在于RUN指令本身,关键在于:

  • 你会不会手动安装nginx?
  • 你会不会linux的shell脚本语法?
  • 你能不能把nginx的安装过程写成shell脚本?

如果上面三个问题的答案都是肯定的,用RUN指令即可执行shell脚本完成软件的安装。这也是Dockerfile编写内容的核心所在,linux shell并不是本文要为大家说明的内容。

COPY

COPY指令的作用是将本地文件(执行镜像构建所在的服务器),拷贝到镜像文件中。语法是:​​COPY <本地文件路径>:<镜像文件路径>​​,镜像文件路径同时也是容器运行时文件系统的路径。

COPY docker-entrypoint.sh /

COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d

COPY 20-envsubst-on-templates.sh /docker-entrypoint.d

COPY 30-tune-worker-processes.sh /docker-entrypoint.d

如果本地文件路径只有文件名,就是表示文件和Dockerfile在同一个目录下(相对路径语法)。即:下面的这些文件在同一个目录(这些文件在我上文给出的nginx官方Dockerfile连接中都可以看到)。

​另外可以使用WORKDIR 指令为 Dockerfile 中跟随它的任何 RUN、CMD、ENTRYPOINT、COPY、ADD 指令设置本地工作目录。这样上文提到的相对路径,就是相对WORKDIR指定路径的相对路径。但是通常情况下,不建议使用WORKDIR,因为很难保证执行构建的开发者工作主机的工作路径和Dockerfile编写者的工作路径都是一致的。

WORKDIR  /root

ENTRYPOINT

一个Dockerfile中如果定义多个ENTRYPOINT,只有最后一条ENTRYPOINT生效,并且每次启动docker容器,都会执行ENTRYPOINT指定的脚本。对于nginx:1.23.3而言,"/docker-entrypoint.sh"脚本中定义了nginx配置检查及nginx服务的启动指令。所以通常情况下ENTRYPOINT指定的脚本通常都是镜像内核心服务的启动脚本。

这个脚本中最后执行了nginx服务启动,需要配合CMD命令完成,参考下文的CMD命令。

​EXPOSE

Docker 容器在运行时暴漏指定的网络端口,可用于容器端口映射,默认协议是 TCP。格式如下:

EXPOSE <端口号>

EXPOSE <端口号>/<协议>

例子:

​​EXPOSE 80

​EXPOSE 80/tcp

EXPOSE 80/udp

将容器端口暴露出去后,可以与宿主机的端口建立映射关系,这样可以通过访问宿主机的端口来访问容器内部的服务。比如同时在 TCP、UDP 上暴露容器的80端口。


STOPSIGNAL

STOPSIGNAL SIGQUIT

docker-nginx在github上的issues里面给出的答案是,之所以加上STOPSIGNAL信号的目的是:避免docker容器停止后,nginx服务不能正确终止造成僵尸进程的存在。

CMD
CMD指令也是用来执行linux命令或脚本,这一点和RUN指令是一致的。二者的区别在于

CMD指令是在执行docker run指令时被执行,也就是创建容器时执行;而RUN指令实在镜像构建的时候执行,即docker bulid时候执行。
也正因为指令的执行期不同,RUN命名执行的写入操作被写入到镜像层。CMD指令执行结果包含写入操作,被写入到容器层。
所以CMD和ENTRYPOINT 指令有点相似,都是在创建容器时运行。需要注意的是:一旦Dockerfile中包含ENTRYPOINT指令,CMD指令就作为ENTRYPOINT指定的脚本的参数存在。参考下文格式语法。
CMD包含三种格式:

第一种为ENTRYPOINT指定的脚本传参,上文中的ENTRYPOINT脚本最后一行的exec "@"调用CMD命令进行容器服务的启动。

CMD ["nginx", "-g", "daemon off;"]

第二种 执行一个命令或shell脚本,可以传参,注意是双引号。与第一种格式语法是一样的,只是没有ENTRYPOINT指定脚本,所以不作为ENTRYPOINT指定脚本的参数存在。

CMD ["executable","param1","param2"]

第三种为普通的执行shell脚本的语法,如执行echo "This is a test." | wc -cshell命令行。笔者说:在Dockerfile中这种方法不要用,没必要知道为什么。

CMD echo "This is a test." | wc -c


文档参考:

​https://blog.csdn.net/hanxiaotongtong/article/details/124441548​




标签:get,--,apt,nginx,&&,docker,dockerfile
From: https://blog.51cto.com/wyf1226/5963268

相关文章

  • 神器 Nginx 的学习手册 ( 建议收藏 )
    Nginx是一个高性能的HTTP和反向代理服务器,特点是占用内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网页服务器中表现较好。Nginx专为性能优化而开发,性能是......
  • nvidia-docker安装
    (1)确保NVIDIADrivers和Docker已经安装好$nvcc--version$docker(2)安装nvidia-docker(2.1)设置stable存储库和密钥#注意此步骤可能无法下载,需要手动去网页下载,......
  • Centos安装Docker、Docker-compose
    Docker的搭建Docker版本要求要求CentOs7系统的内核版本高于3.10,可通过如下指令查看版本uname-r更新yum需先安装必要的软件包,yum-utils、device-mapper-persisten......
  • SpringBoot项目Jar包构建Docker镜像
    在jar包同级目录创建Dockerfile文件,写入一下:FROMopenjdk:11MAINTAINERdemoADD[jar包文件][生成的镜像名称]EXPOSE8110//镜像暴露的端口号ENTRYPOINT["java",......
  • Docker容器配置Nacos、Sentinel
    nacosdockerrun-d-p8848:8848--namenacos--restart=always--envMODE=standalone--envSPRING_DATASOURCE_PLATFORM=mysql--envMYSQL_SERVICE_HOST=140.2......
  • Nginx 解决跨域问题(CORS)
    CORS(Cross-OriginResourceSharing)跨域资源共享,是一种允许当前域(domain)的资源(比如html/js/webservice)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略(thes......
  • docker安装ELK
    一、elasticsearch(仅用于测试环境)1、拉取镜像(docker版本19.03.9)dockerpullelastic/elasticsearch:7.10.22、创建挂载目录mkdir-p/data/elk/es/{config,data,log......
  • Docker学习笔记十四:Docker安装Grafana
    介绍是一个开源的度量分析和可视化工具,可以通过将采集的数据分析、查询,然后进行可视化的展示,并能实现报警。参考官网地址:https://grafana.com/docs/grafana/latest/inst......
  • Linux部署docker镜像之PHP项目的Dockerfile步骤
    二、Docker部署步骤1、项目编译成镜像请cd到和Dockerfile同目录;例如:cd/home/docker dockerbuild-twebsite:latest.2、查看镜像并创建容器 dockerimages ......
  • CenterOS7安装docker
    CenterOS7安装docker官方文档卸载旧版本sudoyumremovedocker\docker-client\docker-client-latest\......