予枫个人主页 个人专栏: 《Java 从入门到起飞》《读研码农的干货日常》 Debug 这个世界Return 更好的自己引言作为Docker容器化的核心Dockerfile是构建自定义镜像的“说明书”新手入门常被FROM、COPY等指令搞晕尤其分不清CMD和ENTRYPOINT的区别。本文从零开始拆解4个最常用的Dockerfile指令搭配极简Hello World实战手把手教你写出第一个可运行的Dockerfile新手也能快速上手收藏起来慢慢练文章目录一、DOCKERFILE 核心认知二、常用指令详解必学4个2.1 FROM指定基础镜像必备第一条2.2 COPY复制文件到镜像中2.3 WORKDIR指定工作目录2.4 CMD vs ENTRYPOINT容器启动命令重点区分2.4.1 CMD容器启动默认命令2.4.2 ENTRYPOINT容器启动入口命令2.4.3 核心区别总结新手必记三、实战写一个最简单的Hello World服务的Dockerfile3.1 实战准备3.2 编写文件内容3.2.1 编写app.sh脚本3.2.2 编写Dockerfile3.3 构建镜像启动容器实战操作3.3.1 构建镜像3.3.2 启动容器四、结尾总结一、DOCKERFILE 核心认知Dockerfile是一个纯文本文件包含了一系列有序的指令每一条指令对应镜像构建的一个步骤。通过docker build命令Docker会自动读取Dockerfile中的指令一步步构建出我们需要的镜像最终基于镜像启动容器。核心优势可复用一份Dockerfile可在任意支持Docker的环境中构建镜像解决“环境不一致”难题可版本控制Dockerfile可纳入Git管理便于追溯镜像构建逻辑的变更自动化结合CI/CD可实现镜像自动构建、部署提升开发效率小贴士新手写Dockerfile记住一个原则——“每一条指令只做一件事”既能保证镜像精简也能减少构建错误。记得点赞收藏后续实战不迷路二、常用指令详解必学4个这4个指令是Dockerfile入门的核心覆盖了“基础镜像选择、文件复制、工作目录设置、容器启动命令”四大核心场景吃透它们就能应对80%的入门场景。2.1 FROM指定基础镜像必备第一条作用指定构建当前镜像所依赖的基础镜像相当于“搭建地基”所有后续指令都基于这个基础镜像执行。语法FROM 镜像名称:标签说明标签可选默认是latest最新版本但生产环境建议指定具体标签如ubuntu:22.04避免版本变更导致异常基础镜像可以是官方镜像如ubuntu、alpine也可以是自定义镜像每一个Dockerfile必须以FROM指令开头注释除外示例# 基于ubuntu 22.04官方镜像作为基础镜像 FROM ubuntu:22.042.2 COPY复制文件到镜像中作用将宿主机本地的文件或目录复制到构建中的镜像指定路径下。语法COPY 宿主机路径 镜像内路径说明宿主机路径是相对于Dockerfile所在目录的相对路径不能使用绝对路径除非使用COPY . /xxx复制当前目录所有文件如果镜像内路径不存在Docker会自动创建该路径可复制单个文件、多个文件或整个目录示例# 将宿主机当前目录下的app.py文件复制到镜像的/usr/src/app目录下 COPY app.py /usr/src/app/ # 将宿主机当前目录下的所有文件复制到镜像的/usr/src/app目录下 COPY . /usr/src/app/2.3 WORKDIR指定工作目录作用设置后续指令如COPY、CMD、ENTRYPOINT的工作目录相当于“进入镜像中的某个文件夹”后续指令都在该目录下执行。语法WORKDIR 镜像内目录路径说明如果指定的目录不存在Docker会自动创建该目录可多次使用WORKDIR每次使用都会切换到新的目录类似cd命令推荐使用WORKDIR避免在COPY、CMD中使用复杂的路径提升可读性示例# 设置工作目录为/usr/src/app后续指令都在此目录下执行 WORKDIR /usr/src/app # 此时COPY指令相当于将宿主机app.py复制到/usr/src/app/app.py COPY app.py .2.4 CMD vs ENTRYPOINT容器启动命令重点区分这两个指令都用于指定容器启动时执行的命令新手最容易混淆核心区别CMD可被覆盖ENTRYPOINT不可被覆盖具体拆解如下2.4.1 CMD容器启动默认命令作用指定容器启动时默认执行的命令若启动容器时手动指定了命令会覆盖CMD的默认命令。语法常用两种Exec格式推荐CMD [可执行文件, 参数1, 参数2]注意用双引号逗号分隔Shell格式CMD 命令 参数1 参数2示例# Exec格式容器启动时执行echo Hello Docker CMD [echo, Hello Docker] # 启动容器时手动指定命令会覆盖CMD # docker run -it 镜像名称 echo Hello World → 输出Hello World而非默认内容2.4.2 ENTRYPOINT容器启动入口命令作用指定容器启动时必须执行的命令无法被启动容器时的手动命令覆盖只能通过--entrypoint参数修改。语法常用Exec格式ENTRYPOINT [可执行文件, 参数1, 参数2]说明常与CMD配合使用ENTRYPOINT指定固定命令CMD指定默认参数启动容器时可修改CMD的参数适合用于构建“专用容器”如固定执行某个服务确保容器启动必执行指定命令示例配合使用# ENTRYPOINT指定固定命令echoCMD指定默认参数Hello Docker ENTRYPOINT [echo] CMD [Hello Docker] # 启动容器时可修改CMD的参数不改变ENTRYPOINT # docker run -it 镜像名称 Hello Entrypoint → 输出Hello Entrypoint2.4.3 核心区别总结新手必记指令是否可被覆盖核心用途CMD是启动容器时手动命令覆盖指定容器默认启动命令可修改ENTRYPOINT否仅–entrypoint可修改指定容器固定启动入口不可改小贴士新手入门建议优先使用CMD熟悉后再根据需求搭配ENTRYPOINT避免一开始混淆用法 觉得有用的话麻烦点赞支持一下后续更新更多Docker实战技巧三、实战写一个最简单的Hello World服务的Dockerfile学会上面4个指令我们直接上手实战编写一个极简的Hello World Dockerfile构建镜像后启动容器就能看到输出结果全程不到10行代码新手可直接复制操作。3.1 实战准备本地安装Docker已安装可跳过未安装的同学自行搜索对应系统安装教程新建一个空目录如dockerfile-demo在目录中创建两个文件Dockerfile无后缀和app.sh脚本文件用于输出Hello World3.2 编写文件内容3.2.1 编写app.sh脚本#!/bin/bash# 输出Hello World同时打印当前时间echoHello World! 当前时间$(date)3.2.2 编写Dockerfile# 1. 指定基础镜像选择轻量的alpine镜像体积更小 FROM alpine:3.18 # 2. 设置工作目录 WORKDIR /usr/src/demo # 3. 复制宿主机的app.sh脚本到镜像中 COPY app.sh . # 4. 给app.sh添加执行权限alpine镜像默认无执行权限 RUN chmod x app.sh # 5. 指定容器启动命令执行app.sh脚本 CMD [./app.sh]说明新增了RUN指令简单提一句用于在构建镜像时执行命令如给文件加权限后续进阶教程会详细拆解新手先了解即可。3.3 构建镜像启动容器实战操作在Dockerfile所在目录执行以下命令复制即可执行3.3.1 构建镜像# docker build -t 镜像名称:标签 . 末尾的.表示当前目录的Dockerfiledockerbuild -t hello-docker:v1.执行成功后用docker images命令可看到构建好的hello-docker:v1镜像3.3.2 启动容器# docker run 镜像名称:标签dockerrun hello-docker:v1执行后会看到输出Hello World! 当前时间xxx时间为容器内的当前时间说明Dockerfile编写成功、镜像构建正常、容器启动成功实战总结这个极简案例完美用到了FROM、COPY、WORKDIR、CMD四个核心指令新手可反复练习修改app.sh的内容重新构建镜像、启动容器感受Dockerfile的作用四、结尾总结本文从零开始拆解了Dockerfile入门必备的4个核心指令FROM、COPY、WORKDIR、CMD vs ENTRYPOINT重点区分了新手易混淆的CMD和ENTRYPOINT最后通过一个极简的Hello World实战让大家亲手体验Dockerfile的编写、镜像构建和容器启动全过程。Dockerfile是Docker容器化的基础后续复杂的镜像构建都是基于这些核心指令的延伸建议新手先吃透本文内容多动手实战避免死记硬背慢慢就能熟练编写Dockerfile。我是予枫专注分享Docker、Python、后端开发相关干货关注我后续更新更多Docker进阶技巧多阶段构建、镜像优化等带你从新手成长为容器高手欢迎在评论区留言说说你写Dockerfile时踩过的坑一起交流学习