【DOCKER容器实战】-5 Docker容器镜像的构建

Docker 容器镜像的构建

文章目录

  • [Docker 容器镜像的构建](#Docker 容器镜像的构建)
    • 一、获取容器镜像的四种方式
    • 二、方式二:打包操作系统文件系统为镜像
      • [1. 打包根文件系统](#1. 打包根文件系统)
      • [2. 导入为本地镜像](#2. 导入为本地镜像)
      • [3. 运行验证](#3. 运行验证)
      • 小结
    • [三、方式三:把正在运行的容器打包为镜像(docker commit)](#三、方式三:把正在运行的容器打包为镜像(docker commit))
      • [1. 运行容器](#1. 运行容器)
      • [2. 在容器中安装应用](#2. 在容器中安装应用)
      • [3. 把正在运行的容器打包为镜像](#3. 把正在运行的容器打包为镜像)
      • [4. 测试新镜像](#4. 测试新镜像)
      • 知识点
    • [四、方式四:通过 Dockerfile 构建镜像](#四、方式四:通过 Dockerfile 构建镜像)
      • [Dockerfile 简介](#Dockerfile 简介)
      • [Dockerfile 指令分类](#Dockerfile 指令分类)
    • [实战一:构建 SSH 镜像](#实战一:构建 SSH 镜像)
      • [1. 环境准备](#1. 环境准备)
      • [2. 编写 Dockerfile](#2. 编写 Dockerfile)
      • [3. 逐行解析](#3. 逐行解析)
      • [4. 构建镜像并启动容器](#4. 构建镜像并启动容器)
      • [5. SSH 登录验证](#5. SSH 登录验证)
      • [6. 整体功能总结](#6. 整体功能总结)
    • [实战二:构建 Nginx 镜像](#实战二:构建 Nginx 镜像)
      • [1. 环境准备](#1. 环境准备)
      • [2. 编写 Dockerfile](#2. 编写 Dockerfile)
      • [3. 逐行解析](#3. 逐行解析)
      • [4. 编写容器启动脚本](#4. 编写容器启动脚本)
      • [5. 构建与运行](#5. 构建与运行)
    • [实战三:构建 Tomcat 镜像](#实战三:构建 Tomcat 镜像)
      • [1. 环境准备](#1. 环境准备)
      • [2. 编写 Dockerfile](#2. 编写 Dockerfile)
      • [3. 构建镜像](#3. 构建镜像)
      • [4. 简要解读](#4. 简要解读)

一、获取容器镜像的四种方式

  1. DockerHub 直接下载:拉取官方或社区已构建好的镜像。
  2. 打包操作系统文件系统 :用 tar 打包根文件系统,再用 docker import 生成镜像。
  3. 打包正在运行的容器 :用 docker commit 把容器当前状态保存为镜像。
  4. Dockerfile 自定义构建 :编写 Dockerfile,用 docker build 生成自定义镜像。

\[03_云原生/Docker/image/cababa847874663a4059671fe48cc0a1_MD5.jpg\|Open: Pasted image 20261017162559.png\]

!\[03_云原生/Docker/image/cababa847874663a4059671fe48cc0a1_MD5.jpg]

\[03_云原生/Docker/image/66a603b9175e78380adab9749c93dcfc_MD5.jpg\|Open: Pasted image 20261017162612.png\]

!\[03_云原生/Docker/image/66a603b9175e78380adab9749c93dcfc_MD5.jpg]


二、方式二:打包操作系统文件系统为镜像

适用场景 :只能自己使用的特殊架构环境。这也是"多云变更包"的由来。

流程 :最小安装 CentOS 7 → tar 打包根文件系统 → (远程传输到目标主机)→ docker import 生成镜像。

1. 打包根文件系统

shell 复制代码
[root@localhost ~]# tar --numeric-owner --exclude=/proc --exclude=/sys -cvf centos7.tar /
  • --numeric-owner:保留文件的 UID/GID 数字编号,保证导入 Docker 后权限正常。
  • --exclude=/proc、--exclude=/sys:排除虚拟文件系统。容器运行时与宿主机共享这两个目录,不需要打包。

2. 导入为本地镜像

把打包好的文件导入 Docker,生成本地容器镜像:

shell 复制代码
[root@localhost ~]# ls
anaconda-ks.cfg  centos7.tar

# 把 tar 归档包导入 Docker,生成镜像 centos7:v1
[root@localhost ~]# docker import centos7.tar centos7:v1
sha256:6a2dab2deae802cc67f76c072bc6fbb64cd4bdd1ee1a9cd7ae7d2ebd2babaaeb

# 查看本地镜像列表
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
centos7       v1        6a2dab2deae8   7 seconds ago   1.37GB
centos        test      0569b4534598   46 hours ago    204MB
nginx         latest    22bd15417453   9 days ago      192MB
redis         latest    0378d73bea8b   2 weeks ago     128MB
tomcat        latest    9ca267cc83c7   2 weeks ago     468MB
mysql         5.7       5107333e08a8   19 months ago   501MB
elasticsearch 7.17.0    6fe993d6e7ed   3 years ago     612MB
kibana        7.17.0    9c9fdad81115   3 years ago     888MB
centos        7         eeb6ee3f44bd   3 years ago     204MB
redis         5.0.7     7eed8df88d3b   5 years ago     98.2MB

!tip

如果打包和导入不在同一台机器上:先把 centos7.tar 远程传输到目标主机,再执行同样的 docker import 命令即可。

\[03_云原生/Docker/image/8053e879db7fb75d0612c013ee9e50e3_MD5.jpg\|Open: Pasted image 20261017163238.png\]

!\[03_云原生/Docker/image/8053e879db7fb75d0612c013ee9e50e3_MD5.jpg]

3. 运行验证

shell 复制代码
[root@localhost ~]# docker run -it centos7:v1 bash
[root@2bf858099ffe /]# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
32: eth0@if33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    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
  • docker run -it centos7:v1 bash:基于刚导入的镜像交互式启动容器,进入 bash 终端。
  • ip a s:查看容器内部网卡信息。
    • lo:本地回环网卡,127.0.0.1
    • eth0:容器网卡,IP 为 172.17.0.2(Docker 默认 bridge 网桥网段)

小结

  • 步骤:tar 打包 → docker import 导入 → docker run 验证。
  • 不需要 /proc、/sys,因为容器与宿主机共享。
  • 适合只能自己用的特殊架构:tar 打包 + import 变成镜像。

三、方式三:把正在运行的容器打包为镜像(docker commit)

1. 运行容器

shell 复制代码
[root@localhost ~]# docker run -it centos7:v1 bash

2. 在容器中安装应用

shell 复制代码
[root@928a6eca9f1d /]# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
[root@928a6eca9f1d /]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
[root@928a6eca9f1d /]# yum install httpd -y

安装完成后按 Ctrl+P+Q 退出容器------容器保持后台运行,不会关闭。

3. 把正在运行的容器打包为镜像

shell 复制代码
[root@localhost ~]# docker commit 928a6eca9f1d centos7-httpd:v1
sha256:f7ced4266c17f1d7d5b2d4483edef0ba7405d9186c822b5a771b454758a397fb

[root@localhost ~]# docker images
REPOSITORY    TAG IMAGE ID     CREATED         SIZE
centos7-httpd v1  f7ced4266c17 10 seconds ago  1.67GB

4. 测试新镜像

shell 复制代码
# 启动新容器,确认 httpd 已预装
[root@localhost ~]# docker run -it centos7-httpd:v1 bash
[root@035005f4b471 /]# rpm -qa | grep httpd
httpd-2.4.6-99.el7.centos.1.x86_64
httpd-tools-2.4.6-99.el7.centos.1.x86_64

# 启动 httpd 并访问首页
[root@035005f4b471 /]# httpd -k start
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
[root@035005f4b471 /]# curl http://localhost

知识点

  1. Ctrl+P+Q:退出容器但不关闭容器,容器保持后台运行。
  2. docker commit 容器ID 镜像名:标签:将当前运行中的容器打包生成新镜像。
  3. 新镜像 centos7-httpd:v1 自带 httpd 服务,后续 run 出来的容器预装好了 httpd。

四、方式四:通过 Dockerfile 构建镜像

Dockerfile 简介

Dockerfile 是一种能被 Docker 程序解释的构建脚本文本文件 ,由一条一条指令组成,有自己的书写格式和支持的命令。当我们需要在容器镜像中指定自己的需求时,只需在 Dockerfile 上添加或修改指令,然后通过 docker build 生成自定义的容器镜像(image)。

构建流程对比:

方式 命令 说明
运行中的容器 → 镜像 docker commit 快照式打包,不可追溯
Dockerfile → 镜像 docker build 指令化构建,可重复、可追溯

Dockerfile 指令分类

构建类指令 ------用于构建 image 的设置类指令,其指定的操作不会在运行 image 的容器上执行:

  • FROM、MAINTAINER、RUN、ENV、ADD、COPY

设置类指令 ------用于设置 image 的属性,其指定的操作将在运行 image 的容器中执行:

  • CMD、ENTRYPOINT、USER、EXPOSE、VOLUME、WORKDIR、ONBUILD

\[03_云原生/Docker/image/5e3837e1ca133a3c8ea6147c41af5057_MD5.jpg\|Open: Pasted image 20261017164743.png\]

!\[03_云原生/Docker/image/5e3837e1ca133a3c8ea6147c41af5057_MD5.jpg]


实战一:构建 SSH 镜像

1. 环境准备

shell 复制代码
[root@localhost ~]# mkdir -p /docker_work/sshd
[root@localhost ~]# cd /docker_work/sshd/

2. 编写 Dockerfile

shell 复制代码
[root@localhost sshd]# vim Dockerfile
dockerfile 复制代码
FROM centos:7
MAINTAINER The CentOS Project <cloud-centos>
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum -y update
RUN yum -y install openssh* net-tools lsof telnet passwd
RUN echo '123456' | passwd --stdin root
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
EXPOSE 22
CMD ["/usr/sbin/sshd" , "-D"]

\[03_云原生/Docker/image/e5ff034b99f6b5af60f2ac93cfb8c6db_MD5.jpg\|Open: Pasted image 20261017170341.png\]

!\[03_云原生/Docker/image/e5ff034b99f6b5af60f2ac93cfb8c6db_MD5.jpg]

3. 逐行解析

  1. FROM centos:7

    基础镜像,基于官方 centos:7 镜像 开始构建,所有后续指令都在这个系统里执行。FROM 是 Dockerfile 必须有的第一条指令。

  2. MAINTAINER The CentOS Project <cloud-centos>

    镜像维护者信息(已废弃指令 ,新标准推荐用 LABEL maintainer="xxx",但老教程还在用),仅做备注,不影响镜像功能。

  3. RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup

    RUN:在镜像构建阶段执行 shell 命令。把系统自带的 yum 源配置文件改名备份,准备替换成阿里云源。

  4. RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

    下载阿里云 CentOS7 yum 源,覆盖原 repo 文件,加速国内 yum 下载。

  5. RUN yum -y update

    更新系统所有已安装软件包到最新版本,-y 自动确认,不需要手动交互。

  6. RUN yum -y install openssh* net-tools lsof telnet passwd

    一次性安装依赖包:

    • openssh*:ssh 全套服务(sshd 服务端、ssh 客户端)
    • net-tools:ifconfig、netstat 等老网络命令
    • lsof:查看文件/端口占用
    • telnet:远程测试连通性工具
    • passwd:修改用户密码工具
  7. RUN echo '123456' | passwd --stdin root

    设置 root 密码为 123456。--stdin:从管道读取密码,不需要交互式输入------Docker 构建时不能交互,必须用这种方式。

    !warning 安全隐患

    密码硬编码在镜像里,任何人拿到镜像都知道 root 密码,生产严禁这么写。

  8. RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config

    sed -i 直接修改文件。修改 ssh 配置文件:关闭 PAM 认证。Docker 容器环境默认 PAM 会阻碍 root 远程登录,所以关闭。

  9. RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

    生成 ssh 主机 RSA 私钥。sshd 服务启动必须要有主机密钥文件;centos 基础镜像不带这个文件,不生成 sshd 无法启动。

    • -t rsa:密钥类型 rsa
    • -f:指定密钥保存路径
  10. RUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd

    注释掉 pam 配置里 pam_loginuid.so 这一行。pam_loginuid 在容器环境会报错,导致 ssh 登录失败,注释掉规避这个限制。

  11. RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh

    • 创建 root 的 ssh 目录 /root/.ssh(密钥 / authorized_keys 存放目录)
    • 设置 /root 目录属主为 root
    • .ssh 权限设置 700:仅 root 用户可读可写,ssh 强制要求这个权限,权限过大 ssh 拒绝登录
  12. EXPOSE 22

    声明容器打算开放 22 端口(ssh 默认端口)。只是文档声明,不会真正打开端口 ;真正端口映射要在 docker run -P / -p 的时候指定。

  13. CMD ["/usr/sbin/sshd" , "-D"]

    容器启动默认执行的命令:前台运行 sshd 服务。

    • /usr/sbin/sshd:ssh 服务程序
    • -D:让 sshd 以前台方式运行(非常关键 )。Docker 容器机制:容器内前台进程退出,容器就停止 。不加 -D,sshd 后台启动,容器启动后立刻退出。

4. 构建镜像并启动容器

shell 复制代码
# 构建镜像(. 代表当前目录作为构建上下文)
[root@localhost sshd]# docker build -t sshd:v1 .

# 后台启动容器,-P 自动映射 22 端口到宿主机随机端口
[root@localhost sshd]# docker run -d -P sshd:v1
7a5f87e554e42ed1fafd36c097bba98c0ae86b870cf143bb7ca529c76e93819e

5. SSH 登录验证

shell 复制代码
[root@localhost sshd]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS       PORTS                                         NAMES
7a5f87e554e4   sshd:v1   "/usr/sbin/sshd -D"      3 seconds ago Up 2 seconds 0.0.0.0:32768->22/tcp, :::32768->22/tcp        ecstatic_matsumoto

[root@localhost sshd]# ssh localhost -p 32768
The authenticity of host '[localhost]:32768 ([::1]:32768)' can't be established.
RSA key fingerprint is SHA256:k3pMBnY5o0njrCGIjyFY2c1NsOwuWCgk4+xtg1UJG1A.
RSA key fingerprint is MD5:0d:0d:68:2f:fd:fb:d7:81:97:d2:53:63:9a:0f:8b:5c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:32768' (RSA) to the list of known hosts.
root@localhost's password:
[root@7a5f87e554e4 ~]#
  • docker ps -a 查看所有容器。PORTS 列 0.0.0.0:32768->22/tcp 表示:宿主机 32768 端口转发到容器的 22 端口。
  • ssh localhost -p 32768:在宿主机本地 ssh 连接,-p 指定端口,密码是 Dockerfile 设置的 123456。
    • 首次连接提示主机指纹,输入 yes 确认信任主机
    • 输入 root 密码后成功登录容器内部,提示符变成 [root@7a5f87e554e4 ~]#(7a5f87e554e4 就是容器 ID)

6. 整体功能总结

这个 Dockerfile 的作用:基于 centos7,替换阿里 yum 源,安装 openssh 服务,修改 ssh 与 pam 配置、生成密钥、设置 root 密码,构建一个可以被外部 ssh 远程连接的容器镜像。启动容器后,宿主机 ssh 可以直接连容器内的 root 账号。

!question 缺点(面试常问)

  1. root 密码硬编码在镜像,安全风险极大
  2. 多个 RUN 指令会生成多层镜像,镜像体积偏大,可以合并 RUN 减少层数
  3. 关闭 PAM、开放 root 直接密码登录,不符合生产安全规范

实战二:构建 Nginx 镜像

1. 环境准备

shell 复制代码
[root@localhost sshd]# mkdir /docker_work/nginx
[root@localhost sshd]# cd /docker_work/nginx/
  • 把 nginx 源码包(nginx-1.12.0.tar.gz)放入 /docker_work/nginx/ 目录,后续 Dockerfile 会复制源码进镜像编译安装。
  • vim Dockerfile:编辑 Dockerfile 构建脚本,用来编译安装 nginx 自制镜像。

2. 编写 Dockerfile

dockerfile 复制代码
#基于基础镜像
FROM centos:7
#用户信息
MAINTAINER this is nginx image <chen>
#添加环境包
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum -y update
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
#下载nginx软件包
ADD nginx-1.12.0.tar.gz /usr/local/src
WORKDIR /usr/local/src
#指定工作目录
WORKDIR 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
#指定http和https端口
EXPOSE 80
EXPOSE 443

RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
#添加宿主机中run.sh到容器中
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]

3. 逐行解析

  1. FROM centos:7

    基础镜像,以 centos7 作为底层系统。

  2. MAINTAINER this is nginx image <chen>

    镜像维护者信息,旧版指令。

  3. 换阿里 yum 源(备份原 yum 源 → 替换阿里云源 → 更新系统软件):

    dockerfile 复制代码
    RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
    RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    RUN yum -y update
  4. RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make

    安装源码编译 nginx 所需依赖:

    • gcc/gcc-c++:C 语言编译器
    • pcre-devel:正则库,nginx rewrite 依赖
    • zlib-devel:gzip 压缩模块依赖
    • make:编译工具
  5. RUN useradd -M -s /sbin/nologin nginx

    创建 nginx 运行用户:

    • -M:不创建家目录
    • -s /sbin/nologin:禁止登录,安全用户
  6. ADD nginx-1.12.0.tar.gz /usr/local/src

    ADD 会自动解压 tar 包:把宿主机当前目录下的 nginx-1.12.0.tar.gz 复制到镜像内 /usr/local/src 并解压。

  7. WORKDIR /usr/local/src

    设置工作目录。

  8. WORKDIR nginx-1.12.0

    进入解压出来的 nginx 源码目录 /usr/local/src/nginx-1.12.0。

  9. 编译安装 nginx:

    dockerfile 复制代码
    RUN ./configure \
    --prefix=/usr/local/nginx \
    --user=nginx \
    --group=nginx \
    --with-http_stub_status_module && make && make install
    • --prefix:安装路径
    • --user / --group:指定运行身份为 nginx 用户
    • --with-http_stub_status_module:开启状态监控模块
    • && make && make install:编译 + 安装
  10. ENV PATH /usr/local/nginx/sbin:$PATH

    添加 nginx 的 sbin 目录到系统环境变量 PATH,直接输入 nginx 命令即可执行。

  11. EXPOSE 80 / EXPOSE 443

    声明对外提供 80(http)、443(https)端口,仅文档声明,不会实际开放端口。

  12. RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf

    重点 :向 nginx 配置追加 daemon off;,让 nginx 以前台方式运行。Docker 容器依赖前台进程存活;nginx 默认后台守护运行,不加这个容器会直接退出。

  13. ADD run.sh /run.sh

    将宿主机的 run.sh 脚本复制到镜像根目录。

  14. RUN chmod 755 /run.sh

    给脚本增加执行权限。

  15. CMD ["/run.sh"]

    容器启动时默认执行 /run.sh 脚本,脚本内部用来启动 nginx。

4. 编写容器启动脚本

shell 复制代码
[root@localhost nginx]# vim run.sh

run.sh 脚本内容:

shell 复制代码
#!/bin/bash
/usr/local/nginx/sbin/nginx
  • #!/bin/bash:脚本声明,指定用 bash 解释器执行脚本
  • /usr/local/nginx/sbin/nginx:启动 nginx 服务
  • 该脚本放在宿主机的 /docker_work/nginx 目录(构建上下文目录),Dockerfile 通过 ADD run.sh /run.sh 复制进镜像内
  • Dockerfile 里 CMD ["/run.sh"],容器启动时自动执行该脚本拉起 nginx

!tip 整体逻辑

容器启动 → 执行 /run.sh → 脚本启动 nginx(配合 daemon off; 前台运行)→ nginx 作为容器 1 号进程维持容器存活。

5. 构建与运行

shell 复制代码
# 查看目录结构
[root@localhost nginx]# tree ./
./
├── Dockerfile
├── nginx-1.12.0.tar.gz
└── run.sh

0 directories, 3 files

# 构建镜像(. 为构建上下文)
[root@localhost nginx]# docker build -t nginx:new .

# 运行容器
[root@localhost nginx]# docker run -d -P nginx:new
e2c1cb27027609ca0ca0c8148c667bb2b46145c4415c34321c44eee413b62d84

# 查看容器状态
[root@localhost nginx]# docker ps
CONTAINER ID   IMAGE       COMMAND    CREATED         STATUS    PORTS                                                               NAMES
e2c1cb276   nginx:new   "/run.sh"   5 seconds ago   Up 4s     0.0.0.0:32770->80/tcp, :::32770->80/tcp, 0.0.0.0:32769->443/tcp, :::32769->443/tcp   boring_bhabha
  • -d:后台守护运行
  • -P(大写 P):随机端口映射,自动把容器内 EXPOSE 声明的 80、443 端口映射到宿主机随机高端口
  • PORTS 列:宿主机 32770 映射容器 80,宿主机 32769 映射容器 443

!tip

浏览器访问 宿主机IP:32770 即可打开 nginx 页面。


实战三:构建 Tomcat 镜像

1. 环境准备

shell 复制代码
[root@localhost nginx]# mkdir /docker_work/tomcat
[root@localhost nginx]# cd /docker_work/tomcat/

把 jdk-8u91-linux-x64.tar.gz、apache-tomcat-8.5.16.tar.gz 放入 /docker_work/tomcat 目录中。

2. 编写 Dockerfile

shell 复制代码
[root@localhost tomcat]# vim Dockerfile
dockerfile 复制代码
FROM centos:7
MAINTAINER this is tomcat image <chen>
ADD jdk-8u91-linux-x64.tar.gz /usr/local
WORKDIR /usr/local/
RUN mv jdk1.8.0_91 /usr/local/java
ENV JAVA_HOME /usr/local/java
ENV JAVA_BIN /usr/local/java/bin
ENV JRE_HOME /usr/local/java/jre
ENV PATH $PATH:/usr/local/java/bin:/usr/local/java/jre/bin
ENV CLASSPATH /usr/local/java/jre/bin:/usr/local/java/lib:/usr/local/java/jre/lib/charsets.jar
ADD apache-tomcat-8.5.16.tar.gz /usr/local
WORKDIR /usr/local/
RUN mv apache-tomcat-8.5.16 /usr/local/tomcat8
EXPOSE 8080
#CMD ["/usr/local/tomcat8/bin/startup.sh","run"]
ENTRYPOINT ["/usr/local/tomcat8/bin/catalina.sh","run"]

3. 构建镜像

shell 复制代码
[root@localhost tomcat]# docker build -t tomcat:v1 .

4. 简要解读

  1. ADD:自动解压 jdk、tomcat 压缩包到容器内 /usr/local。
  2. RUN mv:重命名文件夹,方便环境变量配置。
  3. 一连串 ENV:配置 Java 环境变量(JAVA_HOME、JAVA_BIN、JRE_HOME、PATH、CLASSPATH)。
  4. EXPOSE 8080:声明 tomcat 端口。
  5. ENTRYPOINT ["/usr/local/tomcat8/bin/catalina.sh","run"]
    • catalina.sh run:前台运行 tomcat,作为容器主进程,容器不会直接退出
    • 注释掉了 CMD,这里使用 ENTRYPOINT 作为容器启动入口

!note 知识点

catalina.sh run 是前台启动;如果是 startup.sh 是后台启动,会导致容器启动后立刻退出。

相关推荐
闲云自留地3 小时前
K8s 的记忆大脑!ETCD 集群部署、etcdctl 命令与备份恢复全通关
容器·kubernetes·etcd
讯捷蓝达3 小时前
戴尔R720xd服务器卡死在 “Configuring Memory...Done“,换了内存还是卡?问题根本不在内存
运维·服务器
爱和冰阔落5 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
lisanmengmeng6 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮7 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
上火的金鱼妹7 小时前
k8s生产实际问题排查(网关,数据库读写等)
运维·服务器
孙克旭_7 小时前
k8s基础组件与创建资源
运维·docker·容器·kubernetes
孙克旭_7 小时前
云原生基础之Containerd容器运行时
运维·云原生
分布式存储与RustFS7 小时前
RustFS 自建对象存储实战目录:110 篇按场景分类(持续更新)
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
无忧_wy7 小时前
MoneyPrinterTurbo 自动化视频生成实战指南
运维·人工智能·自动化·音视频