docker-Dockerfile

时间:2022-07-26
本文章向大家介绍docker-Dockerfile,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Dockerfile是为了快速构建镜像 Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。 一般而言,Dockerfile分为4个部分: 基础镜像信息<br/>维护者信息<br/>镜像操作指令<br/>容器启动时执行指令

Dockerfile指令:

(1)FROM
指定所创建镜像的基础镜像,如果本地不存在,则默认会去Docker Hub下载指定镜像。
格式:FROM &lt;image&gt;或 FROM &lt;image&gt;:&lt;tag&gt;
任何Dockerfile中的第一条指令必须为FROM指令。并且在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)
(2)MAINTAINER
格式:MAINTAINER &lt;name&gt;,指定维护者信息
该信息会写入生成镜像的Author属性域中
(3)RUN
运行指定命令。
格式:RUN &lt;command&gt;或RUN ["executable","param1","param2"]。注意,后一个指令会被解析为Json数组,因此必须用双引号。
前者默认将在shell终端运行命令,即/bin/sh -c;后者则使用exec执行,不会启动shell环境。
比如:RUN yum install httpd
RUN ["/bin/bash","-c","echo hello"]
每条RUN指令将在当前镜像基础上执行指定命令,并提交为新镜像。当命令过长时,可以使用来换行。
(4)CMD
CMD指令用来指定启动容器时默认执行的命令。
支持3种格式:
•CMD ["executable", "param1", "param2"]<br/>•CMD command param1 param2<br/>•CMD ["param1", "param2"]
RUN和CMD看起来很像,但是CMD用来指定容器启动时用到的命令,只能有一条。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时,指定了运行命令,则会覆盖掉CMD指定的命令。
比如:CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"]
(5)EXPOSE
声明镜像内服务所监听的端口
格式:EXPOSE &lt;port&gt; [&lt;port&gt;...]
比如:EXPOSE 22 80 443
告诉Docker服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过-P,Docker主机会自动分配一个端口转发到指定端口;使用-p,则可以具体指定哪个本地端口映射过来。
(6)ENV
格式:ENV &lt;key&gt; &lt;value&gt;或ENV &lt;key&gt;=&lt;value&gt;,指定一个环境变量,会被后续RUN指令使用,在镜像启动的容器中也会存在。
比如:ENV PATH /usr/local/mysql/bin:$PATH
(7)ADD
格式:ADD &lt;src&gt; &lt;dest&gt;
将本地的一个文件或目录拷贝到容器的某个目录里。其中&lt;src&gt;为Dockerfile所在目录的相对路径,它也可以是一个URL;如果为tar文件,会自动解压到&lt;dest&gt;路径下。&lt;dest&gt;可以是镜像内的绝对路径,或者相对于工作目录(WORKDIR)的相对路径。
• ADD &lt;conf/vhosts&gt; &lt;/usr/local/nginx/conf&gt;
(8)COPY
格式:COPY &lt;src&gt; &lt;dest&gt;
复制本地主机的&lt;src&gt;(为Dockerfile所在目录的相对路径,文件或目录)为容器中的&lt;dest&gt;。目录路径不存在时,会自动创建。当使用本地目录为源目录时,推荐使用COPY。
(9)ENTRYPOINT
指定镜像的默认入口命令,该入口命令在启动容器时作为根命令执行,所有传入值作为该命令的参数
两种格式:
ENTRYPOINT ["executable", "param1", "param2"] (exec调用执行)<br/>ENTRYPOINT command param1 param2 (shell中执行)
此时,CMD指令指定值将作为根命令的参数
配置容器启动后执行的命令,并且不可被docker run 提供的参数覆盖,每个Dockerfile中只能有一个ENTRYPOINT,当指定多个ENTRYPOINT时,只有最后一个生效。
在运行时,可以被--entrypoint参数覆盖掉,如docker run --entrypoint
•我们在Dockerfile中指定如下CMD:
• CMD ["/bin/echo", "test"]
• 启动容器的命令是 docker run aming这样会输出test
• 假如启动容器的命令是 docker run -it aming /bin/bash 什么都不会输出
• ENTRYPOINT不会被覆盖,而且会比CMD或者docker run指定的命令要靠前执行
• ENTRYPOINT ["echo", "test"]
• docker run -it aming 123
• 则会输出 test 123,这相当于要执行命令 echo test 123
(10)VOLUME
创建一个数据卷挂载点
格式:VOLUME ["/data"]
创建一个可以从本地主机或其他容器挂载的挂载点,一般用于存放数据库和需要保持的数据等。
(11)USER
格式:USER daemon
指定运行容器时的用户名或UID,后续的RUN也会指定用户。
当服务不需要管理员权限时,可以通过该指令指定运行的用户。并且可以在之前创建所需要的用户。例如:
RUN groupadd -r postgres && useradd -r -g postgres postgres。要临时获取管理员权限可以使用gosu,而不推荐sudo
(12)WORKDIR
格式:WORKDIR /path/to/workdir
为后续的RUN,CMD,ENTRYPOINT指令配置工作目录。可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:
WORKDIR /a<br/>WORKDIR b<br/>WORKDIR c<br/>RUN pwd
则最终路径为:/a/b/c
(13)ARG
指定一些镜像内使用的参数(例如版本号信息等),这些参数在执行docker build命令时,才以--build-arg&lt;varname&gt;=&lt;value&gt;格式传入
格式:ARG&lt;name&gt;[=&lt;default value&gt;]
则可以用docker build --build-arg&lt;name&gt;=&lt;value&gt;.来指定参数值
(14)ONBUILD
配置当所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作指令。
格式:ONBUILD [INSTRUCTION]
例如,Dockerfile使用如下的内容创建了镜像image-A:
[...]<br/>ONBUILD ADD . /app/src<br/>ONBUILD RUN /usr/local/bin/python-build --dir /app/src<br/>[...]
如果基于image-A创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像,会自动执行ONBUILD指令的内容
(15)STOPSIGNAL
指定所创建镜像启动的容器接收退出的信号值。例如:
STOPSIGNAL signal
(16)HEALTHCHECK
配置所启动容器如何进行健康检查(如何判断健康与否),自docker 1.12开始支持
格式有两种:
HEALTHCHECK [OPTIONS] CMD command:根据所执行命令返回值是否为0来判断;
HEALTHCHECK NONE:禁止基础镜像中的健康检查。
OPTION支持:
①--interval=DURATION(默认为:30s):过多久检查一次;
②--timeout=DURATION(默认为:30s):每次检查等待结果的超时;
③--retries=N(默认为:3):如果失败了,重试几次才最终确定失败。
(17)SHELL
指定其他命令使用shell时的默认shell类型
SHELL ["executable","parameters"]
默认值为["/bin/sh","-c"]

build镜像

Usage: docker build [OPTIONS] PATH | URL | -[flags]Options:
-t, --tag list # 镜像名称
-f, --file string # 指定Dockerfile文件位置
# docker build .
# docker build -t shykes/myapp .
# docker build -t shykes/myapp -f /path/Dockerfile /path
# docker build -t shykes/myapp http://www.example.com/Dockerfile

构建业务基础镜像

构建php基础镜像

[root@localhost php]# vim Dockerfile-php
FROM centos:7
MAINTAINER dev.ceba.com
RUN yum install epel-release -y && 
    yum install -y gcc gcc-c++ make gd-devel libxml2-devel 
    libcurl-devel libjpeg-devel libpng-devel openssl-devel 
    libmcrypt-devel libxslt-devel libtidy-devel autoconf 
    iproute net-tools telnet wget curl && 
    yum clean all && 
    rm -rf /var/cache/yum/*

RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && 
    tar zxf php-5.6.36.tar.gz && 
    cd php-5.6.36 && 
    ./configure --prefix=/usr/local/php 
    --with-config-file-path=/usr/local/php/etc 
    --enable-fpm --enable-opcache 
    --with-mysql --with-mysqli --with-pdo-mysql 
    --with-openssl --with-zlib --with-curl --with-gd 
    --with-jpeg-dir --with-png-dir --with-freetype-dir 
    --enable-mbstring --with-mcrypt --enable-hash && 
    make -j 4 && make install && 
    cp php.ini-production /usr/local/php/etc/php.ini && 
    cp sapi/fpm/php-fpm.conf /usr/local/php/etc/php-fpm.conf && 
    sed -i "90a daemonize = no" /usr/local/php/etc/php-fpm.conf && 
    mkdir /usr/local/php/log && 
    cd / && rm -rf php* && 
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ENV PATH $PATH:/usr/local/php/sbin
COPY php.ini /usr/local/php/etc/
COPY php-fpm.conf /usr/local/php/etc/
WORKDIR /usr/local/php
EXPOSE 9000
CMD ["php-fpm"]

构建nginx基础镜像

[root@localhost nginx]# vim Dockerfile-nginx 
FROM centos:7
MAINTAINER dev.cabe.com
RUN yum install -y gcc gcc-c++ make 
    openssl-devel pcre-devel gd-devel 
    iproute net-tools telnet wget curl && 
    yum clean all && 
    rm -rf /var/cache/yum/*
RUN wget http://nginx.org/download/nginx-1.15.5.tar.gz && 
    tar zxf nginx-1.15.5.tar.gz && 
    cd nginx-1.15.5 && 
    ./configure --prefix=/usr/local/nginx 
    --with-http_ssl_module 
    --with-http_stub_status_module && 
    make -j 2 && make install && 
    rm -rf /usr/local/nginx/html/* && 
    echo "ok" >> /usr/local/nginx/html/status.html && 
    cd / && rm -rf nginx-1.15.5* && 
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ENV PATH $PATH:/usr/local/nginx/sbin
#COPY nginx.conf /usr/local/nginx/conf/nginx.conf
WORKDIR /usr/local/nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

部署lnmp网站平台

1、自定义网络
[root@localhost nginx]# docker network create lnmp
b445b2fd52081134427849986ca3db98b5e888185f51018d0dbea58eaf5bc6e2
2、创建Mysql容器
[root@localhost nginx]# docker run -d 
--name lnmp_mysql 
--net lnmp 
--mount src=mysql-vol,dst=/var/lib/mysql 
-e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=wordpress mysql:5.7 --character-set-server=utf8
3、创建PHP容器
[root@localhost nginx]# docker run -d --name lnmp_php --net lnmp --mount src=wwwroot,dst=/wwwroot php:v1
4、创建Nginx容器
[root@localhost nginx]# docker run -d --name lnmp_nginx --net lnmp -p 80:80 
--mount type=bind,src=$(pwd)/nginx.conf,dst=/usr/local/nginx/conf/nginx.conf --mount src=wwwroot,dst=/wwwroot nginx:v1

[root@localhost nginx]# docker volume ls
DRIVER              VOLUME NAME
local               mysql-vol
local               wwwroot

浏览器访问

部署wordpress博客为例 https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz

[root@localhost ~]# wget https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz
[root@localhost ~]# tar xf wordpress-4.9.4-zh_CN.tar.gz 
[root@localhost ~]# mv wordpress /var/lib/docker/volumes/wwwroot/_data/

配置连接数据库

部署成功

构建tomcat基础镜像

[root@localhost tomcat]# vim Dockerfile-tomcat 
FROM centos:7
MAINTAINER dev.ceba.com

ENV VERSION=8.0.53

RUN yum install java-1.8.0-openjdk wget curl unzip iproute net-tools -y && 
    yum clean all && 
    rm -rf /var/cache/yum/*

#RUN wget http://192.168.31.211/apache-tomcat-${VERSION}.tar.gz && 
RUN wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz && 
    tar zxf apache-tomcat-${VERSION}.tar.gz && 
    mv apache-tomcat-${VERSION} /usr/local/tomcat && 
    rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/* && 
    mkdir /usr/local/tomcat/webapps/test && 
    echo "ok" > /usr/local/tomcat/webapps/test/status.html && 
    sed -i '1a JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"' /usr/local/tomcat/bin/catalina.sh && 
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ENV PATH $PATH:/usr/local/tomcat/bin

WORKDIR /usr/local/tomcat

EXPOSE 8080
CMD ["catalina.sh", "run"]

[root@localhost tomcat]# docker build -t tomcat:v1 -f Dockerfile-tomcat .

基于构建的镜像启动容器

[root@localhost tomcat]# docker run -d --name=tomcat_web tomcat:v1
e60b29a7a9b1433a85ee9bd0b4eb258bd84fa5bfa88780bf947d4a65f711e1fb
[root@localhost tomcat]# docker exec tomcat_web ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
67: eth0@if68: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@localhost tomcat]# curl 172.17.0.2:8080/test/status.html
ok

构建项目

[root@localhost tomcat]# vim Dockerfile-tomcat-project 
FROM tomcat:v1
COPY jenkins.war /usr/local/tomcat/webapps/ROOT.war

访问项目