【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 是后台启动,会导致容器启动后立刻退出。

相关推荐
速捷工控 PLC触摸屏还原程序1 小时前
S7-200 SMART程序上传提示密码?维修、改造和换机怎么选处理路径?
运维·服务器
程序员-Benothing2 小时前
Linux抓包分析教程:tcpdump、Wireshark、tshark实战
linux·运维·服务器
QMCY_jason2 小时前
ubuntu x86_64架构的编译 aarch64架构的程序
linux·运维·ubuntu
分布式存储与RustFS2 小时前
RustFS 该跟 stable 还是 nightly?两条版本线的分工、风险与回退,一张表说清
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
无足鸟ICT2 小时前
【RHCA+】rpm命令(安装、升级、卸载和查询)
linux·运维·服务器
吹什么轩2 小时前
linux系统复习:从冯·诺依曼到操作系统:一切的开场
linux·运维·服务器
程序员-Benothing2 小时前
SSH从入门到精通:密钥登录、config配置、跳板机
linux·运维·服务器·ssh
Elastic 中国社区官方博客2 小时前
Jina AI:Elasticsearch 集成
大数据·运维·人工智能·elasticsearch·搜索引擎·全文检索·jina
H.莓飛2 小时前
【Linux】自主 Shell
linux·运维·服务器·c语言·开发语言·visual studio