使用dockerfile创建镜像

1.什么是Dockerfile

Dockerfile 是一个用于指导 Docker 镜像构建过程的脚本文件。它通过一系列指令来详细描述了构建镜像所需的步骤和配置细节。利用 Dockerfile,我们可以精确地设定容器的运行环境,安装必要的软件,复制项目文件,以及配置环境变量等。

Dockerfile 的优势在于其可重复性和自动化,使得应用程序的容器化过程既高效又可靠。通过将构建过程代码化,我们能够对构建步骤进行版本控制,并在不同的环境中复现相同的镜像。

Dockerfile 的组成通常包括以下几个方面:指定基础镜像、提供维护者信息、执行镜像构建指令以及定义容器启动时要运行的命令。

在 Dockerfile 中,指令是按照从上到下的顺序执行的,且首个非注释指令必须是 FROM,用以指定基础镜像。Dockerfile 中的注释以"#"开头。

Dockerfile 支持多种指令,例如 RUN、CMD、FROM、EXPOSE、ENV 等,这些指令帮助我们定义镜像的操作系统、安装软件、设置环境变量等。

编写完 Dockerfile 后,我们可以通过执行 docker build 命令并指定 Dockerfile 的位置来构建镜像。Docker 引擎将按照 Dockerfile 中的指令逐步构建,最终生成一个新的镜像。

综上所述,Dockerfile 是一个关键工具,它通过简洁明了的文本指令,帮助我们自动化和标准化 Docker 镜像的构建过程,从而简化了容器化应用程序的部署工作。

2.Dockerfile 中常用的指令

|-------------|----------------------------------|
| 指令 | 说明 |
| FROM | 指定基础镜像 |
| MAINTAINER | 设置维护者信息 |
| RUN | 在镜像中执行命令 |
| CMD | 指定容器启动时要执行的命令 |
| ENTRYPOINT | 与 CMD 类似,但不会被 docker run 命令行参数覆盖 |
| COPY | 复制文件或目录到镜像中 |
| ADD | 复制文件或目录到镜像中,支持远程 URL 和解压缩功能 |
| ENV | 设置环境变量 |
| ARG | 定义构建时的变量,可以通过 --build-arg 参数传递 |
| WORKDIR | 设置工作目录 |
| USER | 指定运行容器时的用户名或 UID |
| EXPOSE | 声明容器运行时需要监听的端口 |
| HEALTHCHECK | 定义容器的健康检查命令 |
| VOLUME | 声明容器中的挂载点 |
| LABEL | 为镜像添加元数据 |

注意事项:

FROM

  • 尽量使用官方镜像作为基础镜像,以确保稳定性和安全性。
  • 指定镜像时,最好使用具体标签(例如 ubuntu:20.04 而不是 ubuntu:latest),以避免构建时的不一致性。

MAINTAINER(已废弃,推荐使用 LABEL)

  • 请注意,MAINTAINER 指令已被废弃,现在推荐使用 LABEL 指令来设置维护者信息。

RUN

  • 为了保持 Dockerfile 的可读性和可维护性,尽量使用 && 来链式执行命令,并使用 \ 来换行。
  • 尽可能使用 RUN apt-get clean 来清理缓存,减少镜像大小。

CMD

  • CMD 指令的目的是为执行容器提供默认值,如果 docker run 指定了命令,CMD 会被覆盖。
  • 当 Dockerfile 中有多个 CMD 指令时,只有最后一个 CMD 会生效。

ENTRYPOINT

  • ENTRYPOINT 与 CMD 结合使用可以设置容器启动时要执行的默认命令和参数。
  • 使用 ENTRYPOINT ["executable", "param1", "param2"] 的形式可以确保 docker run 的参数被追加到 param1, param2 后面。

COPY 和 ADD

  • 尽可能使用 COPY 而不是 ADD,除非你需要 ADD 的额外功能(如解压缩)。
  • 为了提高可读性,请明确指定源路径和目标路径。

ENV

  • 使用 ENV 来设置环境变量,可以在后续的指令中使用这些变量。
  • 尽量将环境变量设置在 Dockerfile 的顶部,以便于其他指令引用。

ARG

  • ARG 指令定义的变量只在构建时有效,容器运行时不可用。
  • 使用 ARG 定义的变量可以在 docker build 时通过 --build-arg 传递。

WORKDIR

  • 使用 WORKDIR 而不是多个 RUN 指令中的 cd,以确保路径的清晰性和一致性。

USER

  • 使用 USER 指令来指定运行容器的用户,以减少安全风险。

EXPOSE

  • EXPOSE 指令只是声明容器将监听指定的端口,并不会自动映射端口到宿主机。

HEALTHCHECK

  • 使用 HEALTHCHECK 来检测容器的健康状态,这对于自动重启失败的容器很有用。

VOLUME

  • 使用 VOLUME 来管理容器的数据持久化,避免数据丢失。

LABEL

  • 使用 LABEL 来添加元数据,便于组织镜像和记录版本信息。

这些指令可以根据需要灵活组合,构建出符合需求的 Docker 镜像。请注意,Dockerfile 中的指令顺序很重要,因为每个指令都会创建一个新的镜像层,而后续的指令将基于前面的镜像层进行操作。

更详细的指令说明和用法,请参考 Docker 官方文档:

Dockerfile reference | Docker Docs

3.dockerfile基本结构和构建镜像原则

3.1 基本结构

3.2 构建基本原则

dockerfile构建镜像需要遵循一下原则:

  • 单一职责:每个层级只做每个层级的事
  • 提供注释信息:最好提供注释信息,以便他人理解
  • 保持容器最小化
  • 合理选择基础镜像:基础镜像的选择很重要,尽量选择成熟易用的基础镜像版本
  • 最小化镜像层数:镜像层数不宜过多,尽量精简,否则容易出错,也可能会影响加载速度

通过上面的示例图可以看出,每多一行命令,镜像的内容就多一层。

其他注意事项:

  • 尽量减少镜像层数,可以通过合并 RUN 指令来实现。
  • 使用 .dockerignore 文件排除不必要的文件和目录,减少构建上下文的大小。
  • 保持 Dockerfile 的简洁性,避免在其中执行复杂的操作,尽可能在构建上下文中准备数据。
  • 定期更新基础镜像以包含最新的安全补丁。

4.Dockerfile使用示例

4.1 基于centos8镜像构建nginxWeb服务镜像

以下是一个简单的 Dockerfile示例,以构建一个基于 centos 的配置web服务的镜像:

1.创建构建上下文目录:

bash 复制代码
[root@open-Euler3 ~]# mkdir dockerfile_test

2.本地添加nginx测试界面用于COPY

bash 复制代码
[root@open-Euler3 ~]# echo "nginx test" > dockerfile_test/index.html

3.编写Dockerfile文件

bash 复制代码
[root@open-Euler3 dockerfile_test]# cat Dockerfile
# 1. 第一行必须指定基础镜像信息
ARG VER=8
FROM centos:${VER}

# 2. 作者信息
LABEL maintainer="openlab <openlab@123.com>"

# 3. 安装 nginx
RUN mkdir -p /etc/yum.repos.d/bak_repo && \
    mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak_repo/ 2>/dev/null || true && \
    curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo && \
    dnf clean all && \
    dnf makecache && \
    dnf install -y nginx
  
# 4. 复制静态文件
COPY index.html /usr/share/nginx/html

# 5. 暴露端口
EXPOSE 80 443

# 6. 启动服务
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]

4.docker build 构建镜像

注意:-t选项指定构建出镜像的标签 最后的 "." 指定的是当前目录,也就是构建上下文目录,Dockerfile所在的目录

5.查看构建的镜像

bash 复制代码
[root@open-Euler3 dockerfile_test]# docker images
REPOSITORY                   TAG       IMAGE ID       CREATED         SIZE
centos_nginx                 latest    7ca95c53855e   2 minutes ago   342MB
ubuntu                       18.04     f9a80a55f492   21 months ago   63.2MB
reg.yym.com/openlab/ubuntu   18.04     f9a80a55f492   21 months ago   63.2MB
centos                       8         5d0da3dc9764   3 years ago     231MB

6.启动容器并进行测试:

4.2 基于ubuntu镜像配置SSH服务

要求:

1、基础镜像ubuntu:18.04。

2、替换为国内的安装源(比如阿里或163)。

3、安装openssh-server。

4、允许root用户远程登录。

5、暴露端口22。

6、服务开机自启动。

1.创建构建上下文目录:

bash 复制代码
[root@open-Euler3 dockerfile_ssh]# pwd #这是我的构建上下文位置
/root/dockerfile_ssh

2.文件准备

1)apt源:

bash 复制代码
[root@open-Euler3 dockerfile_ssh]# cat 163.list
deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse

2)客户端公钥文件

bash 复制代码
[root@open-Euler3 dockerfile_ssh]# ssh-keygen -f ~/.ssh/id_rsa -P '' -q #生成公私钥
[root@open-Euler3 dockerfile_ssh]# cp ~/.ssh/id_rsa.pub ./authorized_keys

3)准备启动脚本文件

bash 复制代码
[root@open-Euler3 dockerfile_ssh]# cat run.sh
#!/bin/bash
/usr/sbin/sshd -D
[root@open-Euler3 dockerfile_ssh]# chmod +x run.sh

4)编写Dockerfile文件

bash 复制代码
[root@open-Euler3 dockerfile_ssh]# vim Dockerfile
FROM ubuntu:18.04

MAINTAINER "kongd <kongd@11.com>"

RUN mv /etc/apt/sources.list /etc/apt/sources.bak
COPY aliyun.list /etc/apt/sources.list.d/aliyun.list
RUN apt update && apt install -y openssh-server && mkdir -p /var/run/sshd
RUN sed -ri 's/session    required     pam_loginuid.so/#session    required     pam_loginuid.so/' /etc/pam.d/sshd
COPY run.sh /run.sh
RUN chmod +x /run.sh
RUN mkdir /root/.ssh
COPY authorized_keys /root/.ssh/authorized_keys

EXPOSE 22/tcp

CMD ["/run.sh"]

docker build 构建镜像)

查看镜像:

bash 复制代码
[root@open-Euler3 dockerfile_ssh]# docker images
REPOSITORY                   TAG       IMAGE ID       CREATED         SIZE
ssh1_image                   latest    98ea77f917f0   4 minutes ago   248MB
centos_nginx                 latest    fb1d61ed3b60   3 hours ago     342MB
ubuntu                       18.04     f9a80a55f492   21 months ago   63.2MB
reg.yym.com/openlab/ubuntu   18.04     f9a80a55f492   21 months ago   63.2MB
centos                       8         5d0da3dc9764   3 years ago     231MB

通过构建的镜像启动一个容器:

bash 复制代码
[root@open-Euler3 dockerfile_ssh]# docker run -itd --name ssh1_c1 -p 10022:22 ssh1_image
cfec71666b634dfbfea43427cf1846d9516bcc3a9806f923a6391e560a721319
[root@open-Euler3 dockerfile_ssh]# docker ps -a
CONTAINER ID   IMAGE        COMMAND     CREATED         STATUS         PORTS                                     NAMES
cfec71666b63   ssh1_image   "/run.sh"   3 seconds ago   Up 3 seconds   0.0.0.0:10022->22/tcp, :::10022->22/tcp   ssh1_c1

测试ssh免密登录:

可以看到直接通过映射后的宿主机IP+端口登录到容器的shell上。

相关推荐
Tttian62220 分钟前
Spring
java·后端·spring
南山不太冷22 分钟前
Spring(4)——响应相关
java·后端·spring
kill bert25 分钟前
第27周JavaSpringboot电商进阶开发 1.企业级用户验证
java·前端·数据库
拓端研究室TRL3 小时前
R软件线性模型与lmer混合效应模型对生态学龙类智力测试数据层级结构应用
开发语言·r语言
于慨3 小时前
计算机考研C语言
c语言·开发语言·数据结构
请为小H留灯4 小时前
Python中很常用的100个函数整理
开发语言·python
达斯维达的大眼睛4 小时前
QT小项目-简单的记事本
开发语言·qt
轩宇^_^4 小时前
C++ 类与对象的实际应用案例详解
开发语言·c++
oioihoii4 小时前
从零到多页复用:我的WPF MVVM国际化实践
开发语言·c#·wpf