Docker高级管理--Dockerfile镜像制作

目录

一、Docker 镜像管理

1. Docker 镜像结构

2. Dockerfile 介绍

二、Dockerfile 语法基础

1. 基础指令

2. 环境设置指令

3. 文件操作指令

4. 执行命令指令

5. 网络和暴露端口指令

6. 容器挂载指令

三、Dockerfile 案例实施(构建 Nginx 容器)

步骤 1:拉取基础镜像

步骤 2:创建工作目录及文件

创建目录:

编写 Dockerfile(/opt/nginx/Dockerfile):

编写启动脚本 run.sh(与 Dockerfile 同目录):

步骤 3:构建镜像

步骤 4:启动容器(多种方式)

方式 1:简单启动(映射端口 8080→80)

方式 2:挂载卷 + 执行脚本

方式 3:多卷挂载(配置文件 + 网页目录)

步骤 5:测试访问

写入测试页面:

访问 Nginx(假设主机 IP 为 192.168.10.101,端口为 8083):

关键说明

2.案例 2-- 构建 Tomcat 容器

(1)创建工作目录

(2)创建 dockerfile 文件

(3)创建启动脚本

(4)用 dockerfile 生成镜像

(5)运行容器

(6)访问 tomcat 网站

3:案例 3-- 构建 mysql 容器

(1)创建工作目录

(2)创建 dockerfile 文件

(3)编写 mysql 初始化脚本

(4)生成镜像

(5)创建容器

4:案例 4-- 构建 php

(1)创建工作目录

(3)创建 dockerfile (yum 安装安装)

(3)生成镜像

(4)启动容器

四:Dockerfile 语法注意事项

1:指令书写规范

(1)大小写

(2)顺序

(3)注释

2:基础镜像选择

(1)稳定性与安全性

(2)镜像大小

3:文件操作注意

(1)COPY 与 ADD 的区别

(3)文件路径

4:执行命令要点

(1)RUN 命令优化

(2)清理临时文件和缓存

(3)CMD 与 ENTRYPOINT 搭配:

5:环境变量和参数设置

(1)ENV 与 ARG 的区别:

(2)安全性

(3)网络和端口声明

6:缓存利用与清理

(1)缓存机制

(2)缓存清理


一、Docker 镜像管理

Docker 镜像既是 Docker 核心技术,也是应用发布的标准格式。完整的 Docker 镜像可支撑容器运行,容器内安装的服务若需迁移,需将环境及服务生成新镜像。本案例介绍 Docker 镜像创建方法。

1. Docker 镜像结构

镜像由多层构成,可通过 docker history 查看各层内容及大小,每层对应 Dockerfile 一条指令。镜像默认存储于 /var/lib/docker/<storage-driver> 目录,容器在镜像上层添加读写层:容器内文件改动仅写入读写层,删除容器则读写层及改动丢失。

核心特性

  • Dockerfile 每条指令创建新镜像层;
  • 镜像层可缓存复用;
  • 若指令、文件、构建变量变化,对应镜像层缓存失效,后续层缓存也失效;
  • 镜像层不可变:某层添加文件后,下层删除仅隐藏文件,镜像仍包含该文件。

2. Dockerfile 介绍

Dockerfile 是 Docker 解释的脚本,由多条指令组成(每条对应 Linux 命令),定义镜像构建逻辑,解决命令依赖(类似 Makefile)。相比镜像 “黑盒”,Dockerfile 更透明,支持灵活扩展。

二、Dockerfile 语法基础

Dockerfile 是构建镜像的文本文件,包含以下常用指令:

1. 基础指令

指令作用示例
FROM必选,指定基础镜像(新镜像基于此构建)FROM ubuntu:20.04
MAINTAINER(已弃用)指定维护者信息,推荐用 LABEL 替代MAINTAINER John Doe <johndoe@example.com>
LABEL添加元数据(如作者、版本、描述),便于镜像管理LABEL version="1.0" description="Sample" maintainer="John"

2. 环境设置指令

指令作用示例
ENV设置容器运行时的环境变量ENV MYSQL_ROOT_PASSWORD=password
ARG定义构建时的参数(仅构建阶段有效,可通过 --build-arg 覆盖)ARG VERSION=1.0

3. 文件操作指令

指令作用示例
COPY复制本地文件 / 目录到镜像(仅支持本地路径)COPY app.py /app/
ADD类似 COPY,但支持远程 URL 下载自动解压压缩包ADD http://example.com/file.tar.gz /app/
WORKDIR设置后续指令(RUN/CMD 等)的工作目录WORKDIR /app

4. 执行命令指令

指令作用示例
RUN构建镜像时执行命令(如安装依赖),支持多命令串联(&&RUN apt-get update && apt-get install -y python3
CMD容器启动时的默认命令(Dockerfile 中仅最后一个生效,可被 docker run 覆盖)CMD ["python3", "app.py"]
ENTRYPOINT容器启动时的固定命令docker run 后参数会作为其参数,不被覆盖)ENTRYPOINT ["python3"]
CMD ["app.py"](组合实现 python3 test.py

5. 网络和暴露端口指令

指令作用示例
EXPOSE声明容器监听端口(仅为元数据,需通过 docker run -p 实际映射)EXPOSE 8080

6. 容器挂载指令

指令作用示例
VOLUME定义数据卷挂载点(持久化 / 共享数据)VOLUME ["/app/data"]

三、Dockerfile 案例实施(构建 Nginx 容器)

步骤 1:拉取基础镜像

 docker pull centos:7

步骤 2:创建工作目录及文件

  1. 创建目录

     mkdir -p /opt/nginx
    
  2. 编写 Dockerfile/opt/nginx/Dockerfile):

    FROM centos:7
    MAINTAINER nginx project <123456@qq.com>  # 可替换为 LABEL
    RUN yum -y update && yum -y install pcre-devel zlib-devel gcc gcc-c++ make
    RUN useradd -M -s /sbin/nologin nginx  # 创建非登录用户
    ADD nginx-1.12.0.tar.gz /usr/local/    # 假设本地有 nginx 安装包
    WORKDIR /usr/local/nginx-1.12.0
    RUN ./configure \
        --prefix=/usr/local/nginx \
        --user=nginx \
        --group=nginx \
        --with-http_stub_status_module && make && make install
    ENV PATH /usr/local/nginx/sbin:$PATH  # 配置 Nginx 命令路径
    ADD run.sh /run.sh                     # 复制启动脚本
    RUN chmod 755 /run.sh                  # 赋予执行权限
    EXPOSE 80                              # 声明端口
    CMD ["/run.sh"]                        # 启动命令
    
  3. 编写启动脚本 run.sh(与 Dockerfile 同目录):

    #!/bin/bash
    /usr/local/nginx/sbin/nginx -g "daemon off;"  # 前台运行 Nginx
    

步骤 3:构建镜像

确保 nginx-1.12.0.tar.gz 已上传至 /opt/nginx,执行构建:

 docker build -t mynginx .  

步骤 4:启动容器(多种方式)

方式 1:简单启动(映射端口 8080→80)
[root@localhost nginx]# docker run -d -i --name nginx01 -p 8080:80 mynginx
# 注意:-t 会导致 run.sh 不执行,此处用 -i 交互模式
方式 2:挂载卷 + 执行脚本
[root@localhost nginx]# docker run -d -it -p 8081:80 --name nginx02 \
-v /www/html:/web \          # 主机 /www/html → 容器 /web
mynginx /bin/bash -c /run.sh # 显式执行启动脚本
方式 3:多卷挂载(配置文件 + 网页目录)
[root@localhost ~]# mkdir /nginx                # 主机配置目录
[root@localhost ~]# cp /opt/nginx/nginx.conf /nginx  # 复制自定义配置
[root@localhost nginx]# docker run -dit \
-p 8083:80 \
-v /www/html:/web \                     # 网页数据卷
-v /nginx/nginx.conf:/usr/local/nginx/conf/nginx.conf \  # 配置文件挂载
--name nginx04 \
mynginx \
/bin/bash -c /run.sh

步骤 5:测试访问

  1. 写入测试页面

     echo "web test">/www/html/index.html
    
  2. 访问 Nginx(假设主机 IP 为 192.168.10.101,端口为 8083):

    http://192.168.10.101:8083
    

关键说明

  • 镜像构建docker build 需在 Dockerfile 所在目录执行,-t 指定镜像名称。
  • 容器启动-d 后台运行,-p 端口映射,-v 数据卷挂载,--name 容器命名。
  • 启动脚本run.sh 确保 Nginx 前台运行(否则容器会因守护进程退出而停止)。

2.案例 2-- 构建 Tomcat 容器

(1)创建工作目录

[root@localhost ~]# mkdir /opt/tomcat/
[root@localhost ~]# cd /opt/tomcat/

(2)创建 dockerfile 文件

[root@localhost tomcat]# vim dockerfile
FROM centos:7
ADD jdk-8u91-linux-x64.tar.gz /usr/local/
ENV JAVA_HOME /usr/local/jdk1.8.0_91
ENV JAVA_BIN /usr/local/jdk1.8.0_91
ENV JRE_HOME /usr/local/jdk1.8.0_91

ENV PATH $PATH:/usr/local/jdk1.8.0_91/bin:/usr/local/jdk1.8.0_91/jre/bin
ENV CLASSPATH /usr/local/jdk1.8.0_91/jre/bin:/usr/local/jdk1.8.0_91/lib:/usr/local/jdk1.8.0_91/jre/lib/charsets.jar

ADD apache-tomcat-8.5.16.tar.gz /
RUN mv /apache-tomcat-8.5.16 /usr/local/tomcat
EXPOSE 8080
ADD run.sh /run.sh
RUN chmod 775 /run.sh
CMD ["/run.sh"]

(3)创建启动脚本

[root@localhost tomcat]# vim run.sh
#!/bin/bash
/usr/local/tomcat/bin/startup.sh
tailf /run

备注:
tailf /run //让启动脚本始终运行

(4)用 dockerfile 生成镜像

[root@localhost tomcat]# docker build -t mytomcat .

(5)运行容器

[root@localhost tomcat]# docker run -d -i -p 8080:8080 --name tomcat01 mytomcat

(6)访问 tomcat 网站

http://192.168.10.101:8080

3:案例 3-- 构建 mysql 容器

(1)创建工作目录

[root@localhost ~]# mkdir /opt/mysql

(2)创建 dockerfile 文件

[root@localhost ~]# cd /opt/mysql/
[root@localhost mysql]# vim dockerfile
FROM centos:7
RUN rm -rf /etc/yum.repos.d/*
#ADD CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum clean all
RUN yum -y install mariadb mariadb-server
RUN chown -R mysql:mysql /var/lib/mysql
ADD init.sh /init.sh
RUN chmod 775 /init.sh
RUN /init.sh
EXPOSE 3306
CMD ["mysqld_safe"]

(3)编写 mysql 初始化脚本

[root@localhost mysql]# vim init.sh
#!/bin/bash
mysql_install_db --user=mysql
sleep 3
mysqld_safe &
sleep 3
mysqladmin -u "root" password "123456"
mysql -uroot -p123456 -e "grant all privileges on *.* to 'root'@'%' identified by '123456';"
mysql -uroot -p123456 -e "grant all privileges on *.* to 'root'@'localhost' identified by '123456';"
mysql -uroot -p123456 -e "flush privileges;"

(4)生成镜像

[root@localhost mysql]# docker build -t mysql .

(5)创建容器

[root@localhost mysql]# docker run -id -p 3306:3306 mysql
[root@localhost mysql]# yum -y install mysql
[root@localhost mysql]# mysql -uroot -p123456 -h 192.168.10.101 -P 3306

4:案例 4-- 构建 php

(1)创建工作目录

[root@localhost ~]# mkdir /opt/php
[root@localhost ~]# cd /opt/php

(3)创建 dockerfile (yum 安装安装)

[root@localhost php]#vim dockerfile
FROM centos:7
MAINTAINER jacker
RUN rm -rf /etc/yum.repos.d/*
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum clean all
RUN yum install epel-release -y && yum install -y php php-fpm php-common php-mysqlnd
EXPOSE 9000
CMD ["php-fpm"]

(3)生成镜像

[root@localhost php]# docker build -t myphp .

(4)启动容器

[root@localhost php]# docker run -d -i -p 9000:9000 myphp /bin/bash

四:Dockerfile 语法注意事项

在编写 Dockerfile 时,掌握基础语法的注意事项能够帮助你构建出高效、可靠且易于维护的 Docker 镜像。以下是一些关键的注意事项:

1:指令书写规范

(1)大小写

Dockerfile 中的指令不区分大小写,但建议使用大写,以增强可读性。例如,使用 FROM、RUN 而非 from、run。

(2)顺序

指令的顺序非常重要,因为 Docker 会按顺序依次执行这些指令。合理安排指令顺序有助于提高构建效率和镜像的可维护性。例如,将不常变动的指令放在前面,充分利用 Docker 构建缓存机制。

(3)注释

可以使用 # 来添加注释,这有助于解释 Dockerfile 中各部分的作用,提高代码的可读性。

2:基础镜像选择

(1)稳定性与安全性

选择稳定、官方且维护良好的基础镜像,这样能保证镜像的安全性和可靠性。例如,官方的 ubuntu、alpine 等镜像都有较好的维护和更新机制。

(2)镜像大小

如果对镜像大小有严格要求,可选择轻量级的基础镜像,如 alpine 镜像,它体积小巧,适合构建资源占用少的容器。

3:文件操作注意

(1)COPY 与 ADD 的区别

  • COPY 仅用于简单的文件和目录复制,语法清晰,性能较好,推荐优先使用。
  • ADD 除复制功能外,还支持从 URL 下载文件和自动解压压缩文件,但功能复杂可能带来安全风险和不可预测性,所以仅在确实需要这些额外功能时使用。

(3)文件路径

使用相对路径时要确保路径在构建上下文中是正确的。构建上下文是指执行 docker build 命令时指定的目录,只有该目录下的文件和子目录才能被复制到镜像中。

4:执行命令要点

(1)RUN 命令优化

尽量将多个相关的命令合并成一个 RUN 指令,减少镜像的层数,从而减小镜像体积。例如,使用 && 连接多个命令

(2)清理临时文件和缓存

要及时清理临时文件和缓存,避免将不必要的文件包含在镜像中。如上述示例中使用 rm -rf /var/lib/apt/lists/* 清理 APT 缓存。

(3)CMD 与 ENTRYPOINT 搭配:

  • CMD 为容器提供默认执行命令,ENTRYPOINT 配置容器启动时执行的命令。当两者搭配使用时,CMD 通常作为 ENTRYPOINT 的默认参数。
    例如:
ENTRYPOINT ["python3"]
CMD ["app.py"]
  • 若在 docker run 时指定了命令,CMD 的内容会被覆盖,而 ENTRYPOINT 的命令不会被覆盖,指定的命令会作为参数传递给 ENTRYPOINT。

5:环境变量和参数设置

(1)ENV 与 ARG 的区别:

  • ENV 设置的环境变量在容器运行时持续存在,可被容器内的应用程序使用。
  • ARG 定义的参数仅在镜像构建过程中有效,用于传递构建时的参数。

(2)安全性

避免在 ENV 或 ARG 中设置敏感信息(如密码、密钥等),若确实需要,可以在运行容器时通过环境变量传递。

(3)网络和端口声明

EXPOSE 指令:EXPOSE 只是声明容器监听的端口,不会进行实际的端口映射。在使用 docker run 启动容器时,需使用 -p 或 -P 选项进行端口映射。

6:缓存利用与清理

(1)缓存机制

Docker 构建镜像时会利用缓存,若某条指令的内容未发生变化,会直接使用之前的缓存结果,加快构建速度。因此,将不常变动的指令放在前面,可充分利用缓存。

(2)缓存清理

当需要强制重新构建镜像、不使用缓存时,可使用 docker build --no-cache 命令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值