dockerfile实战指南

以打包hexo以及自己博文为例,进行dockerfile的实战教学。

Dockerfile文件

在自己的hexo根目录之下,创建名为 Dockerfile的文件,名字必须完全相同,区分大小写。

Dockerfile 是一个文本文件,包含了构建 Docker 镜像的所有指令。Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。通过定义一系列命令和参数,Dockerfile 指导 Docker 构建一个自定义的镜像。

指令

这里仅讲解基本的构建镜像的Dockerfile文件指令,详细全部相关指令可自行参见Docker Dockerfile

FROM

用于指定一个基础镜像,该命令是近乎所有Dockerfile文件的第一句命令。
这里选用的镜像是taskbjorn/hexo镜像,需要限制为main版本,latest版本已经近乎停止更新。

1
FROM taskbjorn/hexo:main

taskbjorn/hexo镜像

WORKDIR

用于指定工作路径,和 RUN cd xxx & cmd区别是:

  1. 能创建不存在的路径;
  2. 可以使用环境变量;
  3. 提供运行环境基目录。

对于第3点,重点解释一下。假设我们运行:

1
2
WORKDIR /data
RUN echo "112233" >test.txt

试想一下,能够找到 /data/test.txt文件吗?答案是肯定的。现在更改代码:

1
2
RUN cd /data
RUN echo "112233" >test.txt

试想一下,能够找到 /data/test.txt文件吗?答案是否定的。原因其实很简单,在 Shell 中,连续两行是同一个进程执行环境,因此前一个命令修改的内存状态,会直接影响后一个命令;而在 Dockerfile 中,这两行 RUN 命令的执行环境根本不同,是两个完全不同的容器,执行命令环境信息是完全独立的。这就是对 Dockerfile 的 RUN 指令构建分层存储的概念不了解所导致的错误。

现在,taskbjorn/hexo镜像工作目录是 /home/hexo/.hexo,将工作目录指向它:

1
WORKDIR /home/hexo/.hexo

RUN

在构建过程中在镜像中执行命令。
以创建必要hexo文件夹为例:

1
2
3
4
RUN mkdir scaffolds
RUN mkdir source
RUN mkdir themes
RUN mkdir .github

COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径,路径不存在的话,会自动创建。
以复制hexo文件夹为例:

1
2
3
4
5
6
7
8
9
10
COPY scaffolds/ scaffolds/ 
COPY source/ source/
COPY themes/ themes/
COPY package.json .
COPY _config*.yml .

# 非必要文件,没有这些源文件就删除这部分命令即可
COPY ads.txt .
COPY .github/ .github/
COPY .gitignore .

USER

用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
在安装软件包时,切换为root用户,其余时间切换为普通用户即可。

1
2
3
4
5
6
7
USER root
RUN sed -i 's#https\?://dl-cdn.alpinelinux.org/alpine#https://mirrors.tuna.tsinghua.edu.cn/alpine#g' /etc/apk/repositories
RUN apk update
RUN apk add openssh-client

USER hexo
RUN npm install

EXPOSE

仅仅只是声明端口,没有实际对端口的任何操作。
作用:

  • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
1
EXPOSE 4000

完整代码

这里附上完整的dockerfile代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
FROM taskbjorn/hexo:main


WORKDIR /home/hexo/.hexo


# 创建搬移本地hexo文件
RUN mkdir scaffolds
RUN mkdir source
RUN mkdir themes
RUN mkdir .github

COPY scaffolds/ scaffolds/
COPY source/ source/
COPY themes/ themes/
COPY package.json .
COPY _config*.yml .

## 非必要文件,没有这些源文件就删除这部分命令即可
COPY .github/ .github/
COPY .gitignore .
COPY ads.txt .


# 安装依赖
## 安装ssh
USER root
RUN sed -i 's#https\?://dl-cdn.alpinelinux.org/alpine#https://mirrors.tuna.tsinghua.edu.cn/alpine#g' /etc/apk/repositories
RUN apk update
RUN apk add openssh-client

## 安装npm依赖
USER hexo
RUN npm install


# 暴露端口
EXPOSE 4000

构建

构建使用docker build实现,该命令通过读取 Dockerfile 中定义的指令,逐步构建镜像,并将最终结果保存到本地镜像库中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker build [OPTIONS] PATH | URL | -

PATH: 包含 Dockerfile 的目录路径或 .(当前目录)。
URL: 指向包含 Dockerfile 的远程存储库地址(如 Git 仓库)。
-: 从标准输入读取 Dockerfile。

常用选项:
-t, --tag: 为构建的镜像指定名称和标签。
-f, --file: 指定 Dockerfile 的路径(默认是 PATH 下的 Dockerfile)。
--build-arg: 设置构建参数。
--no-cache: 不使用缓存层构建镜像。
--rm: 构建成功后删除中间容器(默认开启)。
--force-rm: 无论构建成功与否,一律删除中间容器。
--pull: 始终尝试从注册表拉取最新的基础镜像。

使用命令:

1
2
sudo docker build -t lxt_web:v0.0.8 .  # 不输出详细命令输出 比如ls命令等不显示输出
sudo docker build -t lxt_web:v0.0.8 . --progress=plain --no-cache # 输出详细命令输出

输出日志如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[+] Building 36.4s (23/23) FINISHED                                                                                              docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 619B 0.0s
=> [internal] load metadata for docker.io/taskbjorn/hexo:main 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [ 1/18] FROM docker.io/taskbjorn/hexo:main 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 371.18kB 0.1s
=> CACHED [ 2/18] WORKDIR /home/hexo/.hexo 0.0s
=> CACHED [ 3/18] RUN mkdir scaffolds 0.0s
=> CACHED [ 4/18] RUN mkdir source 0.0s
=> CACHED [ 5/18] RUN mkdir themes 0.0s
=> CACHED [ 6/18] RUN mkdir .github 0.0s
=> CACHED [ 7/18] COPY scaffolds/ scaffolds/ 0.0s
=> [ 8/18] COPY source/ source/ 0.0s
=> [ 9/18] COPY themes/ themes/ 0.1s
=> [10/18] COPY package.json . 0.0s
=> [11/18] COPY _config*.yml . 0.0s
=> [12/18] COPY .github/ .github/ 0.0s
=> [13/18] COPY .gitignore . 0.0s
=> [14/18] COPY ads.txt . 0.0s
=> [15/18] RUN sed -i 's#https\?://dl-cdn.alpinelinux.org/alpine#https://mirrors.tuna.tsinghua.edu.cn/alpine#g' /etc/apk/repositories 0.1s
=> [16/18] RUN apk update 1.0s
=> [17/18] RUN apk add openssh-client 1.1s
=> [18/18] RUN npm install 32.5s
=> exporting to image 1.2s
=> => exporting layers 1.2s
=> => writing image sha256:d986c9a8c4886ceba8a01499dafc54ae49af77a26ea4dac3529fc90adeee3387 0.0s
=> => naming to docker.io/library/lxt_web:v0.1.0 0.0s

此时键入sudo docker images查看镜像:

1
2
3
REPOSITORY       TAG       IMAGE ID       CREATED         SIZE
lxt_web v0.1.0 d986c9a8c488 3 minutes ago 279MB
taskbjorn/hexo main a66983e1fe01 5 days ago 124MB

可以看见,lxt_web镜像已经构建完成,至此dockerfile实战结束。

作者

LiXintao

发布于

2025-07-18

更新于

2025-07-20

许可协议

评论