【Docker基础篇】从0到1写Dockerfile:FROM/COPY/CMD/ENTRYPOINT指令详解+Hello World实战


🍃 予枫个人主页
📚 个人专栏 : 《Java 从入门到起飞》《读研码农的干货日常

💻 Debug 这个世界,Return 更好的自己!


引言:作为Docker容器化的核心,Dockerfile是构建自定义镜像的"说明书",新手入门常被FROM、COPY等指令搞晕,尤其分不清CMD和ENTRYPOINT的区别。本文从零开始,拆解4个最常用的Dockerfile指令,搭配极简Hello World实战,手把手教你写出第一个可运行的Dockerfile,新手也能快速上手,收藏起来慢慢练~

文章目录

  • [一、DOCKERFILE 核心认知](#一、DOCKERFILE 核心认知)
  • 二、常用指令详解(必学4个)
    • [2.1 FROM:指定基础镜像(必备第一条)](#2.1 FROM:指定基础镜像(必备第一条))
    • [2.2 COPY:复制文件到镜像中](#2.2 COPY:复制文件到镜像中)
    • [2.3 WORKDIR:指定工作目录](#2.3 WORKDIR:指定工作目录)
    • [2.4 CMD vs ENTRYPOINT:容器启动命令(重点区分)](#2.4 CMD vs ENTRYPOINT:容器启动命令(重点区分))
      • [2.4.1 CMD:容器启动默认命令](#2.4.1 CMD:容器启动默认命令)
      • [2.4.2 ENTRYPOINT:容器启动入口命令](#2.4.2 ENTRYPOINT:容器启动入口命令)
      • [2.4.3 核心区别总结(新手必记)](#2.4.3 核心区别总结(新手必记))
  • [三、实战:写一个最简单的Hello World服务的Dockerfile](#三、实战:写一个最简单的Hello World服务的Dockerfile)
    • [3.1 实战准备](#3.1 实战准备)
    • [3.2 编写文件内容](#3.2 编写文件内容)
      • [3.2.1 编写app.sh脚本](#3.2.1 编写app.sh脚本)
      • [3.2.2 编写Dockerfile](#3.2.2 编写Dockerfile)
    • [3.3 构建镜像+启动容器(实战操作)](#3.3 构建镜像+启动容器(实战操作))
      • [3.3.1 构建镜像](#3.3.1 构建镜像)
      • [3.3.2 启动容器](#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指令开头(注释除外)

示例

dockerfile 复制代码
# 基于ubuntu 22.04官方镜像作为基础镜像
FROM ubuntu:22.04

2.2 COPY:复制文件到镜像中

作用 :将宿主机(本地)的文件或目录,复制到构建中的镜像指定路径下。
语法COPY 宿主机路径 镜像内路径
说明

  • 宿主机路径是相对于Dockerfile所在目录的相对路径,不能使用绝对路径(除非使用COPY . /xxx复制当前目录所有文件)
  • 如果镜像内路径不存在,Docker会自动创建该路径
  • 可复制单个文件、多个文件或整个目录

示例

dockerfile 复制代码
# 将宿主机当前目录下的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,避免在COPYCMD中使用复杂的路径,提升可读性

示例

dockerfile 复制代码
# 设置工作目录为/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的默认命令。
语法(常用两种):

  1. Exec格式(推荐):CMD ["可执行文件", "参数1", "参数2"](注意用双引号,逗号分隔)
  2. Shell格式:CMD 命令 参数1 参数2

示例

dockerfile 复制代码
# 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的参数
  • 适合用于构建"专用容器"(如固定执行某个服务),确保容器启动必执行指定命令

示例(配合使用):

dockerfile 复制代码
# ENTRYPOINT指定固定命令echo,CMD指定默认参数"Hello Docker"
ENTRYPOINT ["echo"]
CMD ["Hello Docker"]

# 启动容器时,可修改CMD的参数(不改变ENTRYPOINT):
# docker run -it 镜像名称 "Hello Entrypoint"  → 输出Hello Entrypoint

2.4.3 核心区别总结(新手必记)

指令 是否可被覆盖 核心用途
CMD 是(启动容器时手动命令覆盖) 指定容器默认启动命令(可修改)
ENTRYPOINT 否(仅--entrypoint可修改) 指定容器固定启动入口(不可改)

小贴士:新手入门建议优先使用CMD,熟悉后再根据需求搭配ENTRYPOINT,避免一开始混淆用法~ 觉得有用的话,麻烦点赞支持一下,后续更新更多Docker实战技巧!

三、实战:写一个最简单的Hello World服务的Dockerfile

学会上面4个指令,我们直接上手实战,编写一个极简的Hello World Dockerfile,构建镜像后启动容器,就能看到输出结果,全程不到10行代码,新手可直接复制操作。

3.1 实战准备

  1. 本地安装Docker(已安装可跳过,未安装的同学自行搜索对应系统安装教程)
  2. 新建一个空目录(如dockerfile-demo),在目录中创建两个文件:Dockerfile(无后缀)和app.sh(脚本文件,用于输出Hello World)

3.2 编写文件内容

3.2.1 编写app.sh脚本

bash 复制代码
#!/bin/bash
# 输出Hello World,同时打印当前时间
echo "Hello World!  当前时间:$(date)"

3.2.2 编写Dockerfile

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 构建镜像

bash 复制代码
# docker build -t 镜像名称:标签 .  (末尾的.表示当前目录的Dockerfile)
docker build -t hello-docker:v1 .
  • 执行成功后,用docker images命令,可看到构建好的hello-docker:v1镜像

3.3.2 启动容器

bash 复制代码
# docker run 镜像名称:标签
docker run 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时踩过的坑,一起交流学习~

相关推荐
weisian1511 小时前
进阶篇-机器学习篇-2--机器学习数学基础:不用啃课本,够用就行
人工智能·机器学习
2501_924878731 小时前
ROI实测:地市级融媒体中心三年TCO较A公司年费制降61.3%(矩阵跃动买断制)
人工智能·逻辑回归·动态规划·语音识别·媒体
Das11 小时前
【机器学习】支持向量机
人工智能·机器学习·支持向量机
山野0201 小时前
从零到上线:Node.js 项目的完整部署流程(包含 Docker 和 CICD)
docker·容器·node.js
小鸡吃米…1 小时前
TensorFlow 实现循环神经网络
人工智能·python·tensorflow
Coder_Boy_2 小时前
Java高级_资深_架构岗 核心面试知识点(AI整合+混合部署)
java·人工智能·spring boot·后端·面试·架构
2501_947908202 小时前
智远纳米科技量产100纳米级以下的材料引领纳米材料量产革命,形成「全球纳米材料障碍」
大数据·人工智能·科技
爱吃rabbit的mq2 小时前
第28章:MLOps基础:机器学习的DevOps
人工智能·机器学习·devops
7B_coder2 小时前
模型推理prefill和decode过程
人工智能·机器学习