Dockerfile 指令及其详细说明:
-
FROM:
- 用途: 指定基础镜像,所有后续指令都将在此镜像基础上进行。
- 语法:
FROM <image>:<tag>
- 示例:
FROM ubuntu:latest
-
RUN:
- 用途: 在构建镜像的过程中执行命令。可以用来安装软件包、修改文件等。
- 语法:
RUN <command>
或RUN ["executable", "param1", "param2"]
(exec形式) - 示例:
RUN apt-get update && apt-get install -y nginx
-
COPY:
- 用途: 从构建上下文目录中复制文件或目录到新的一层的镜像内部。
- 语法:
COPY <src>... <dest>
- 示例:
COPY ./app /usr/local/app
-
ADD:
- 用途: 类似 COPY,但是可以支持自动解压缩和从 URL 下载文件。
- 语法:
ADD <src>... <dest>
- 示例:
ADD https://example.com/archive.tar.gz /app/
-
ENV:
- 用途: 设置环境变量,在后续 RUN、CMD 中可以使用这些变量。
- 语法:
ENV <key> <value>
- 示例:
ENV NODE_ENV production
-
WORKDIR:
- 用途: 设置工作目录,之后的 RUN、CMD、COPY、ADD 等指令都会在这个目录下执行。
- 语法:
WORKDIR <path>
- 示例:
WORKDIR /app
-
CMD:
- 用途: 容器启动时默认执行的命令。可以被
docker run
后面的命令覆盖。 - 语法:
CMD ["executable","param1","param2"]
(exec形式)或CMD command param1 param2
(shell形式) - 示例:
CMD ["npm", "start"]
- 用途: 容器启动时默认执行的命令。可以被
-
ENTRYPOINT:
- 用途: 定义容器启动时运行的命令,通常与 CMD 配合使用,不会被
docker run
后面的命令覆盖。 - 语法: 类似 CMD
- 示例:
ENTRYPOINT ["python", "app.py"]
- 用途: 定义容器启动时运行的命令,通常与 CMD 配合使用,不会被
-
EXPOSE:
- 用途: 声明容器在运行时需要监听的端口,供服务映射。
- 语法:
EXPOSE <port>
- 示例:
EXPOSE 8080
-
VOLUME:
- 用途: 创建一个挂载点,用于持久化数据或共享数据。
- 语法:
VOLUME ["/data"]
- 示例:
VOLUME /var/lib/mysql
-
USER:
- 用途: 指定运行容器时的用户。
- 语法:
USER <user>
- 示例:
USER nobody
-
LABEL:
- 用途: 为镜像添加元数据。
- 语法:
LABEL <key>=<value> <key>=<value>
示例讲解
示例代码
下面是一个java 容器的Dockerfile文件示例
# 使用官方的Java运行时作为父镜像
FROM openjdk:11-jdk-slim
# 设置作者和维护者信息
LABEL author="Author Name"
LABEL maintainer="Maintainer Name <maintainer@example.com>"
# 在容器内创建应用程序目录
WORKDIR /app
# 使用RUN命令创建日志目录
RUN mkdir -p /app/logs && chmod -R 777 /app/logs \
# 可选清理操作,保持镜像更小,根据实际情况决定是否保留
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# 将本地的jar包复制到容器的/app目录下
COPY app.jar /app/app.jar
# 使用环境变量配置应用端口和日志目录
ENV APP_PORT=8080
ENV LOG_DIR=/app/logs
# 暴露容器需要监听的端口
EXPOSE $APP_PORT
# 设置启动容器时执行的命令,并通过JVM参数指定日志输出目录
ENTRYPOINT ["java","-Dlogging.path=$LOG_DIR","-jar","/app/app.jar"]
&& apt-get clean && rm -rf /var/lib/apt/lists/*
这段命令在Dockerfile中主要用于优化生成的镜像,具体作用如下:
apt-get clean
: 这个命令的作用是清理掉apt
命令下载的软件包缓存。当你使用apt-get install
安装软件时,Debian系的系统会把安装包下载到本地的一个缓存目录。执行apt-get clean
后,这些已经下载的包会被删除,从而帮助减少最终镜像的大小。
rm -rf /var/lib/apt/lists/*
: 这个命令则是清空了apt
的lists目录。/var/lib/apt/lists/
目录存储的是所有软件包的列表文件,包括了软件包的版本信息、依赖关系等元数据。在构建镜像过程中,apt-get update
会更新这些列表。执行rm -rf /var/lib/apt/lists/*
会删除这些列表文件,这样做有两点好处:
- 减少镜像体积:因为这些列表文件可能占用一定的空间,尤其是在进行了多次包管理操作后。
- 避免缓存问题:避免了由于列表缓存导致的软件包版本不一致问题,确保每次构建都是基于最新的包列表进行的。
综上所述,这两条命令的组合使用主要是为了清理构建过程中产生的临时文件和缓存,以使得最终构建的Docker镜像更加精简和纯净。这对于追求轻量级、高效部署的Docker镜像来说是非常重要的优化步骤。
运行方式
命令运行方式
# 示例:挂载宿主机的项目文件或日志目录,在运行docker命令时指定
docker run -v $(pwd)/source-code:/app/source-code -v /host/path/to/logs:/app/logs -p 8080:8080 your-image-name
镜像名称或ID:
必须参数,指定要运行的镜像。-a, --attach=[]:
附加到容器的标准输入、输出或错误流。默认情况下,会附加到所有这三个流。-d, --detach:
后台运行容器,并且不会把容器的输出附到当前终端上。-i, --interactive:
保持标准输入打开,通常与-t
一起使用以进入交互式容器。-t, --tty:
分配一个伪TTY,通常用于使交互式进程(如bash)能够正确工作。--name="":
为容器指定一个名称,而不是让Docker自动分配随机名称。-e, --env=[]:
设置环境变量,格式为KEY=VALUE
。-v, --volume=[]:
绑定挂载一个宿主机目录作为数据卷到容器中,格式可以是hostDir:containerDir
或hostDir:containerDir:ro
(只读)。-p, --publish=[]:
映射容器端口到宿主机端口,格式可以是ip:hostPort:containerPort
或ip::containerPort
或hostPort:containerPort
。--network="bridge":
指定容器网络模式,如bridge
,host
,none
, 或自定义网络名。-u, --user="":
指定容器内运行的用户及组,格式USER
或UID:GID
。--restart="no":
容器退出时的重启策略,可选值有no
,on-failure
,always
,unless-stopped
等。-w, --workdir="":
指定容器的工作目录。--memory="":
限制容器可使用的内存总量,例如--memory=2g
。
docker run \
-d \ # 后台运行容器
--name myWebServer \ # 为容器命名,便于管理和日志查看,例如:`docker logs myWebServer`
-e ENV_VAR=value \ # 设置环境变量,例如设置数据库连接字符串:`-e DB_CONN_STR=mysql://user:pass@localhost/dbname`
-v /var/log/nginx:/var/log/nginx:ro \ # 挂载宿主机的Nginx日志目录,确保日志可长期保存和分析
-v ~/myapp/config:/app/config \ # 挂载应用的配置文件夹,方便修改配置而不需重建镜像,如应用的yaml配置
-p 8080:80 \ # 映射容器端口,外部访问容器内服务,如:浏览器访问http://localhost:8080访问容器内Web服务
--network myProjectNet \ # 加入自定义网络,便于容器间通信,例如数据库容器和应用容器在同一网络
-u 1001:1001 \ # 指定运行用户,提升安全性,与宿主机用户ID匹配可避免权限问题
--restart always \ # 自动重启容器,适合生产环境的服务,如Web服务器确保始终在线
-w /usr/src/app \ # 设置工作目录,如Python Flask应用的主目录
--memory 512m \ # 限制资源使用,防止单个容器消耗过多资源影响其他容器或主机性能
my-custom-image:1.0 \ # 指定镜像名称和版本,如个人仓库中的定制化应用镜像
myCommand \ # 默认使用镜像中的ENTRYPOINT/CMD,无需额外指定,除非需要覆盖默认行为