文章目录
- 前言
- 一、docker镜像的分层结构
- 二、dockerfile操作常用指令
- 三、dockerfile构建镜像实战
- [四、Docker Compose 编排](#四、Docker Compose 编排)
-
- 1、概述
- [2、 Docker Compose 环境安装](#2、 Docker Compose 环境安装)
- 3、YMAL文件格式
- [4、Docker Compose配置常用字段](#4、Docker Compose配置常用字段)
- [5、Docker Compose 常用命令](#5、Docker Compose 常用命令)
- [6、Docker Compose 文件结构](#6、Docker Compose 文件结构)
- [五、Docker Compose 编写实战](#五、Docker Compose 编写实战)
- 总结
前言
本文聚焦 Docker 镜像构建与 Compose 编排核心技术,从镜像分层原理、Dockerfile 指令,到多镜像实战与 Compose 配置部署,助力读者掌握容器化应用开发与运维全流程。
一、docker镜像的分层结构
镜像分层 :Docker 镜像不是单一文件,而是由多层文件系统组成。每执行一条 Dockerfile 指令,都会生成新的镜像层。容器启动时会在镜像的只读层上添加一层可读写层。
镜像缓存 :Docker 会缓存每一层的镜像,如果某一层的内容没有变化,则会复用缓存层,以提高构建效率。
总结:Docker 镜像分层是 "只读增量堆叠 + 共享未改内容"
二、dockerfile操作常用指令
1)FROM
指定新镜像基于的基础镜像,Dockerfile 的第一条指令必须为 FROM 。
示例:FROM debian:7 → 基于 Debian 7 系统作为镜像的基础
2) MAINTAINER
指定镜像的维护者信息:
示例:Docker 官方已推荐用 LABEL maintainer="xxx@xxx.com" 替代(更灵活)
比如:LABEL maintainer="testuser test@example.com"。
3) RUN
执行命令并将结果提交到镜像中。常用来安装软件包、修改配置等。
示例:RUN apt-get update && apt-get install -y nginx → 更新源并安装 Nginx。
4)ENTRYPOINT
设置容器启动时默认执行的命令:
示例:ENTRYPOINT ["nginx"] → 容器启动必执行 nginx 命令。
5)CMD
容器启动时执行的默认命令。 CMD 指令会被 docker run 命令后指定的命令覆盖。
示例:CMD ["-g", "daemon off;"] → 给 nginx 加默认参数(让 nginx 前台运行);如果执行 docker run 镜像名 -g "daemon on;",就会覆盖这个 CMD 参数。
6) EXPOSE
声明容器内的端口:
示例:EXPOSE 80 443 → 告诉使用者这个容器会用到 80(HTTP)和 443(HTTPS)端口,运行时需手动加 -p 8080:80 映射。
7) ENV
设置环境变量:后续指令(RUN/COPY/ENTRYPOINT 等)可通过 变量名引用,也能在容器运行时使用示例: E N V N G I N X V E R S I O N = 1.12.2 → 后续 R U N 中可用 n g i n x − 变量名 引用,也能在容器运行时使用 示例:ENV NGINX_VERSION=1.12.2 → 后续 RUN 中可用 nginx- 变量名引用,也能在容器运行时使用示例:ENVNGINXVERSION=1.12.2→后续RUN中可用nginx−{NGINX_VERSION}.tar.gz 引用版本号,改版本时只需改 ENV 一行。
8) ADD
将文件或目录从宿主机复制到镜像中,支持从 URL 下载文件,并能自动解压归档文件
示例:
- ADD nginx.tar.gz /usr/local/ → 把本地压缩包复制到镜像,并自动解压;
- ADD https://xxx.com/file.txt /tmp/ → 从 URL 下载文件到镜像的 /tmp 目录。
9)COPY
将本地文件或目录复制到镜像中
示例:COPY nginx.conf /etc/nginx/ → 把本地的 nginx 配置文件复制到镜像指定目录
10) VOLUME
在容器中创建挂载点
示例:VOLUME ["/var/log/nginx"] → 容器运行时,/var/log/nginx 目录的数据会持久化到宿主机卷中。
11)USER
设置容器内运行命令时的用户
示例:
- 先创建用户:RUN useradd -r nginx;
- 切换用户:USER nginx → 后续命令都以 nginx 普通用户运行(提高安全性)
12)WORKDIR
设置后续指令的工作目录
示例:WORKDIR /tmp → 后续 RUN/COPY/ADD 等指令都在 /tmp 目录下执行,无需写绝对路径。
13)ONBUILD
设置当该镜像作为基础镜像时,后续 Dockerfile 执行的命令
示例:ONBUILD COPY custom.conf /etc/nginx/ → 若有另一个 Dockerfile 基于这个镜像构建,会自动把它本地的 custom.conf 复制到镜像中。
14) HEALTHCHECK
设置容器的健康检查
- --interval=30s:每 30 秒检查一次;
- --timeout=5s:检查命令超时时间 5 秒;
- --retries=3:失败 3 次后标记为不健康。
示例:HEALTHCHECK --interval=30s CMD curl -f http://localhost:80 || exit 1 → 每 30 秒用 curl 访问本地 80 端口,访问失败则返回 1(标记不健康)。
基于指令的完整示例:
# 1. FROM:基础镜像(CentOS 7)
FROM centos:7
# 2. MAINTAINER:维护者(新版推荐用 LABEL,这里保留)
MAINTAINER testuser <test@example.com>
# 3. ENV:环境变量(后续指令引用). doker中定义变量
# nginx版本 和 安装路径
ENV NGINX_VERSION=1.12.2 \
WORK_PATH=/usr/local/nginx
# 4. WORKDIR:设置工作目录(提前创建,避免后续 cd 出错)
# 进入/opt目录,在该目录下下载资源并作后续操作
#RUN/COPY/ADD/ENTRYPOINT 等所有指令,都会以 /tmp 作为 "当前工作目录"。
WORKDIR /opt
# 5. RUN:安装依赖(修复包管理器+包名,新增curl用于健康检查)
RUN yum install -y gcc make pcre-devel zlib-devel wget curl && \
# 下载并解压 Nginx 源码
wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz && \
tar -zxf nginx-${NGINX_VERSION}.tar.gz && \
# 编译安装 Nginx
cd nginx-${NGINX_VERSION} && \
./configure --prefix=${WORK_PATH} && \
make && make install && \
# 清理临时文件(所有/tmp操作完成后清理)
yum clean all && rm -rf /tmp/*
# 6. COPY:复制本地配置文件(需确保本地有nginx-default.conf文件)
#「把你本地电脑里的 nginx-default.conf 文件,复制到正在构建的 Docker 镜像里
# 的 ${WORK_PATH}/conf/ 目录下,并重命名为 nginx.conf」。
COPY ./nginx-default.conf ${WORK_PATH}/conf/nginx.conf
# 7. ADD:下载密钥+解压模块(修复/opt路径,清理后重新创建/opt)
# 从指定的 URL 下载 nginx_signing.key 这个密钥文件,直接放到镜像里的 /opt/ 目录下,并重命名为 nginx.key(如果镜像里没有 /opt 目录,ADD 会自动创建)。
# 为什么要下载这个密钥?
#这是 Nginx 官方的签名密钥,后续如果需要验证 Nginx 安装包的合法性(比如防止包被篡改),就可以用这个密钥做校验,是构建镜像时的 "安全操作"。
#和 COPY 的区别:COPY 只能复制本地文件,没法下载网络文件,这是 ADD 独有的功能。
ADD https://nginx.org/keys/nginx_signing.key /opt/nginx.key
#给 Nginx 加装额外模块(比如防盗链、缓存模块),这些模块打包成压缩包后,用 ADD 一键复制 + 解压,直接放到 Nginx 的模块目录里,启动时就能加载。
ADD ./nginx-modules.tar.gz ${WORK_PATH}/modules/
# 8. EXPOSE:声明端口
# 写了 EXPOSE 80 443,不代表容器启动后,宿主机就能访问 80/443 端口!
# 想要宿主机能访问,必须在启动容器时加 -p 参数
# docker run -p 8080:80 -p 4433:443 你的镜像名
#「给人看」:其他开发者拿到你的镜像,看 docker inspect 镜像名 就能看到 EXPOSE 80 443,立刻知道这个容器需要映射 80/443 端口;
EXPOSE 80 443
# 9. VOLUME:创建挂载点(放在文件复制后,避免覆盖)
# 容器里 Nginx 的日志会直接写到 /宿主机/日志目录,
#网页文件也会和 /宿主机/网页目录 同步,删了容器,宿主机里的日志 / 网页还在。
VOLUME ["/var/log/nginx", "${WORK_PATH}/html"]
# 10. USER:创建并切换用户(CentOS 7 需确保/sbin/nologin存在)
RUN useradd -r -s /sbin/nologin nginx
# 从这行开始,Dockerfile 后续所有指令(HEALTHCHECK、ENTRYPOINT、CMD),
#以及容器启动后运行的 Nginx 进程,都会以 nginx 用户的身份执行,而不是默认的 root。
USER nginx
# 11. HEALTHCHECK:健康检查(修复curl依赖,调整参数)
# Docker 会每隔 30 秒检查一次容器里的 Nginx 是否真的在正常工作,单次检查超时 5 秒,连续 3 次失败就标记容器 "不健康",方便你及时发现 Nginx 挂了。
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -f http://localhost:80 || exit 1
# 12. ENTRYPOINT:修复变量引用(用shell格式解析环境变量)
#容器启动时,必须执行的 "主命令" 是「启动 Nginx」,而且要通过 shell 解析环境变量,还能接收后续的参数(比如 CMD 传的参数)。
ENTRYPOINT ["/bin/sh", "-c", "${WORK_PATH}/sbin/nginx $@"]
# 13. CMD:默认参数(前台运行Nginx)
# 给 ENTRYPOINT 里的 Nginx 命令传默认参数,让 Nginx 以 "前台运行" 的方式启动;如果 docker run 时手动加参数,会替换掉这个默认参数。
CMD ["-g", "daemon off;"]
# 14. ONBUILD:触发器(最后声明)
# 当其他 Dockerfile 把这个镜像当作基础镜像时,才会自动执行这个指令。
# 把「引用者 Dockerfile 同目录下的 custom.conf」复制到镜像的 Nginx 子配置目录
ONBUILD COPY ./custom.conf ${WORK_PATH}/conf/conf.d/
# 15.构建镜像
docker build -t my-web-server .
三、dockerfile构建镜像实战
1、构建SSH镜像
mkdir /opt/sshd
cd /opt/sshd
一定要将yum源文件和Dockerfile 文件放在同一个目录下
cp /etc/yum.repos.d/CentOS-Base.repo ./
vim Dockerfile
#1第一行必须指明基于的基础镜像
FROM centos:7
#2作者信息 MAINTAINER 维护者名称 <维护者邮箱>
MAINTAINER sjj <sjj@example.com>
#3复制本地文件到容器中
ADD CentOS-Base.repo /etc/yum.repos.d/
#4镜像的操作指令
#清理 yum 缓存,因为默认镜像可能有旧的缓存,清理后避免干扰后续操作
RUN yum clean all
#生成新的 yum 缓存,加快后续 yum install 的速度,不用每次安装都重新下载元数据。
RUN yum makecache
RUN yum -y install openssh* net-tools lsof telnet passwd
RUN echo '123456' | passwd --stdin root
#不使用PAM认证
# PAM 是认证模块,关闭它可以避免一些 SSH 登录的权限问题(比如容器内 PAM 配置不全导致登录失败)。
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
#取消pam限制
# 注释掉 pam.d/sshd 里的 session required pam_loginuid.so 这一行,pam_loginuid.so 会检查登录用户的 UID,
# 容器内运行 sshd 时可能因为 UID 映射问题报错,注释掉解决登录问题。
RUN sed -ri '/^session\s+required\s+pam_loginuid.so/ s/^/#/' /etc/pam.d/sshd
#生成密钥认证文件
#生成 SSH 服务需要的 RSA 等密钥文件,sshd 启动时必须有这些密钥,否则会启动失败,-A 是自动生成所有需要的密钥类型。
RUN ssh-keygen -t rsa -A
#创建 root 用户的.ssh 目录(存放 SSH 公钥 / 私钥、authorized_keys 等),设置所属用户为 root,权限 700(只有 root 能读写执行),权限不对会导致 SSH 登录时密钥认证失败。
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
#5声明端口
#声明容器暴露 22 端口(SSH 默认端口),只是声明,不会自动映射,启动容器时需要 - p 2222:22 这样的参数映射。
EXPOSE 22
#6/usr/sbin/sshd -D 用于前台启动sshd服务
# -D是sshd自带的命令,否则会自动关闭掉
# 让 sshd 在前台运行(站在容器内的视角,就是前台运行。宿主机视角有-d决定)
#启动 sshd 服务,-D 参数是让 sshd 在前台运行(不后台守护),因为 Docker 容器的生命周期和前台进程绑定,后台运行的话容器会秒退
# 例如:启动容器,镜像名后加 /usr/sbin/sshd(覆盖原 CMD)
# docker run -d --name sshd-override sshd:centos /usr/sbin/sshd 这个时候容器会退出,因为主进程执行完退出
CMD ["/usr/sbin/sshd" , "-D"]
生成镜像
# 例如在/opt/sshd/目录下执行的构建语句,就会在这个目录找Dockerfile文件等资源
# Dockerfile 名字不能变,构建多个镜像需要创建好目录,在不同目录下执行构建语句
docker build -t sshd:centos . # 如果Dockerfile文件某个路径错了,重新执行即可
启动容器并修改root密码
docker run -d -P sshd:centos
docker ps -a
ssh localhost -p 49153 #映射的端口号。 ssh -p 访问本地的端口

2、构建Systemctl镜像
mkdir /opt/systemctl
cd /opt/systemctl
vim Dockerfile
FROM sshd:centos
MAINTAINER this is systemctl image <hmj>
#在容器里设个 "环境标记",告诉 systemd:"你现在是在 Docker 容器里跑,
#不是在物理机 / 虚拟机里",让它别瞎启动那些只在物理机里才需要的服务(比如开机自检、硬件驱动相关的),避免启动失败。
ENV container docker
#除了systemd-tmpfiles-setup.service,删除其它所有文件
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*; \
rm -f /etc/systemd/system/*.wants/*; \
rm -f /lib/systemd/system/local-f.target.wants/*; \
rm -f /lib/systemd/system/sockets.tsarget.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
#启动这个容器的时候,必须把宿主机的cgroup目录,挂到容器的/sys/fs/cgroup这个位置来",不然 systemctl 没工具用,直接罢工。
#只用需要的服务
VOLUME [ "/sys/fs/cgroup" ]
#CMD ["/usr/sbin/init"]
生成镜像
docker build -t systemd:centos .
启动容器,并挂载宿主机目录挂载到容器中,和进行初始化
#--privileged:使container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限。
docker run --privileged -d -P -v /sys/fs/cgroup:/sys/fs/cgroup:ro systemd:centos /sbin/init
docker ps -a
//进入容器
docker exec -it a1ea25ff5ace bash
systemctl status sshd


3、构建nginx镜像
mkdir /opt/nginx
cd /opt/nginx/
cp /opt/nginx-1.20.2.tar.gz /opt/nginx
vim Dockerfile
#基于基础镜像
FROM centos:7
#用户信息
MAINTAINER this is nginx image <sjj@qq.com>
ADD CentOS-Base.repo /etc/yum.repos.d/
RUN yum clean all
RUN yum makecache
#添加环境包
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
#上传nginx软件压缩包,并解压
ADD nginx-1.20.2.tar.gz /opt/
#指定工作目录
WORKDIR /opt/nginx-1.20.2
RUN ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
#设置环境变量,$PATH保留容器系统原来的PATH
ENV PATH /usr/local/nginx/sbin:$PATH
#指定http和https端口
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf #关闭 nginx 在后台运行
# CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"] (会报错)
CMD ["/usr/local/nginx/sbin/nginx"]
//创建新镜像
docker build -t nginx:centos .
docker run -d -P nginx:centos

4、构建tomcat镜像
mkdir /opt/tomcat
cd /opt/tomcat
cp /opt/jdk-8u91-linux-x64.tar.gz /opt/tomcat
cp /opt/apache-tomcat-8.5.16.tar.gz /opt/tomcat
vim Dockerfile
FROM centos:7
MAINTAINER this is tomcat image <hmj>
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 JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH $JAVA_HOME/bin:$PATH
ADD apache-tomcat-8.5.16.tar.gz /usr/local/
WORKDIR /usr/local/
RUN mv apache-tomcat-8.5.16 /usr/local/tomcat
EXPOSE 8080
#CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
# catalina.sh run 是 Tomcat 专门的前台运行模式 开启前台运行模式
# ENTRYPOINT 不会被覆盖
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]
CMD ["/usr/local/tomcat/bin/startup.sh","start"]
//创建新镜像
docker build -t tomcat:centos .
docker run -d --name tomcat01 -p 1216:8080 tomcat:centos

5、构建mysql镜像
mkdir /opt/mysqld
cd /opt/mysqld
vim Dockerfile
FROM centos:7
MAINTAINER sjj <sjj@qq.com>
RUN yum -y install ncurses ncurses-devel bison cmake pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin mysql
ADD boost_1_59_0.tar.gz /usr/local/src/
ADD mysql-5.7.17.tar.gz /usr/local/src/
RUN mv /usr/local/src/boost_1_59_0 /usr/local/boost
WORKDIR /usr/local/src/mysql-5.7.17/
RUN cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DSYSCONFDIR=/etc \
-DSYSTEMD_PID_DIR=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DWITH_BOOST=/usr/local/boost \
-DWITH_SYSTEMD=1;make -j4;make install
ADD my.cnf /etc/my.cnf
EXPOSE 3306
RUN chown -R mysql:mysql /usr/local/mysql/;chown mysql:mysql /etc/my.cnf
WORKDIR /usr/local/mysql/bin/
RUN ./mysqld \
--initialize-insecure \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data;cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/;systemctl enable mysqld
ENV PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
VOLUME [ "/usr/local/mysql" ]
CMD ["/usr/sbin/init"]
vim my.cnf
[client]
port = 3306
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock
[mysql]
port = 3306
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock
[mysqld]
user = mysql
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port = 3306
character_set_server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket = /usr/local/mysql/mysql.sock
server-id = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
创建新镜像
docker build -t mysql:centos .
启动容器,并进行初始化
docker run --name=mysql_server -d -P --privileged mysql:centos

进入容器,授权远程连接 mysql
docker exec -it mysql_server /bin/bash
mysql -u root -p
grant all privileges on *.* to 'root'@'%' identified by '123456';
grant all privileges on *.* to 'root'@'localhost' identified by '123456';
flush privileges;

在客户端连接mysql容器
本文在windows上通过Navicat连接容器mysql


四、Docker Compose 编排
1、概述
Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。
Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器
(container)。Docker-Compose运行目录下的所有文件(docker-compose.yml,extends文件或环
境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡,比如Consul。
Docker-Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。
2、 Docker Compose 环境安装
# cd /opt 直接拖动docker-compose-v2.24文件,直接赋权使用
mv docker-compose-v2.24.3 /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
#查看版本
docker-compose --version

3、YMAL文件格式
- 大小写敏感:YAML 是大小写敏感的,所以一定要注意区分大小写。
- 缩进:YAML 使用空格进行缩进,不支持 TAB 缩进。通常推荐使用两个空格作为一个层级的缩
进。 - 列表:列表项使用 - (短横线)表示。
- 字典:字典使用 : (冒号)连接键值对,冒号后面需要加一个空格。
- 注释:使用 # 来添加注释。
- 字符串:如果字符串包含特殊字符,可以使用单引号 ' 或双引号 " 来包裹。
4、Docker Compose配置常用字段
build 指定 Dockerfile 文件名
dockerfile 构建镜像上下文路径
context 可以是 dockerfile 的路径,或者是指向 git 仓库的 url 地址
image 指定镜像
command: 执行命令,覆盖容器启动后默认执行的命令
container_name 指定容器名称,由于容器名称是唯一的,如果指定自定义名称,则无法scale指定容器数量
deploy 指定部署和运行服务相关配置,只能在 Swarm 模式使用
environment 添加环境变量
networks 加入网络,引用顶级networks下条目
network_mode 设置容器的网络模式,如 host,bridge,...
ports 暴露容器端口,与 -p 相同,但端口不能低于 60
volumes 挂载一个宿主机目录或命令卷到容器,命名卷要在顶级
volumes 定义卷名称
volumes_from 从另一个服务或容器挂载卷,可选参数 :ro 和 :rw,仅版本 '2' 支持
hostname 容器主机名
sysctls 在容器内设置内核参数
links 连接到另外一个容器,- 服务名称[:服务别名]
privileged 用来给容器root权限,注意是不安全的,true | false
restart 设置重启策略,no,always,nounless-st-failure,oped
no 默认策略,在容器退出时不重启容器。
on-failure 在容器非正常退出时(退出状态非0),才会重启容器。
on-failure:3,在容器非正常退出时重启容器,最多重启3次。
always 在容器退出时总是重启容器。
unless-stopped 在容器退出的容器时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了。
depends_on
在使用Compose时,最大的好处就是少打启动命令,但一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,可能会因为容器依赖问题而启动失败。例如在没启动数据库容器的时候启动应用容器,应用容器
会因为找不到数据库而退出。depends_on标签用于解决容器的依赖、启动先后的问题。
php:
depends_on:
- apache
- mysql
5、Docker Compose 常用命令
字段 描述
build 重新构建服务
ps 列出容器
up 创建和启动容器
exec 在容器里面执行命令
scale 指定一个服务容器启动数量
top 显示容器进程
logs 查看容器输出
down 删除容器、网络、数据卷和镜像
stop/start/restart 停止/启动/重启服务
6、Docker Compose 文件结构
/opt/compose_nginx_tomcat/
├── docker-compose.yml # Docker Compose 配置文件
├── nginx
│ ├── Dockerfile # Nginx 镜像的 Dockerfile
│ └── nginx.conf # Nginx 配置文件
├── tomcat
│ ├── Dockerfile # Tomcat 镜像的 Dockerfile
│ └── webapps
│ └── ROOT.war # Tomcat 应用的 WAR 包
└── wwwroot
└── index.html # 静态文件,Nginx 显示的页面
五、Docker Compose 编写实战
准备nginx镜像构建资源和tomcat构建资源。(上方成功构建的镜像)
配置yml文件
version: '3'
services:
nginx:
container_name: web1
hostname: nginx
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- 1218:80
- 1217:443
networks:
lnmp:
ipv4_address: 172.18.0.10
volumes:
- ./wwwroot:/usr/local/nginx/html
- ./nginxconf/nginx.conf:/usr/local/nginx/conf/nginx.conf
tomcat:
container_name: tomcat
build:
context: ./tomcat
ports:
- "1808:8080" # 将宿主机的8080端口映射到Tomcat的8080端口
networks:
- lnmp
networks:
lnmp:
driver: bridge
ipam:
config:
- subnet: 172.18.0.0/16
将字写入前端资源
echo "123" > wwwroot/index.html


这样就可以访问了,这里触发了反向代理

总结
本文系统讲解 Docker 镜像构建关键技能与 Compose 编排方法,通过多类镜像实战与 Compose 配置演练,帮助读者夯实容器技术基础,提升实际项目部署效率。