下面我来详细讲解 Docker 镜像分层及 dockerfile 编写技巧的完整攻略。
什么是 Docker 镜像分层?
Docker 镜像是由一层层(Layer)堆叠构成的。每个镜像层都是只读的,每次对容器的修改都是在容器新建的一层中进行的。这个特性使得 Docker 镜像具有以下几个优势:
- 镜像分层能够节省存储空间,因为如果多个镜像层中的内容相同,那么它们只需要存储一份即可。
- 镜像分层能够加速镜像的下载和传输,因为只需要下载和传输那些当前所需要的层即可。
- 镜像分层能够提升容器的启动速度。由于只需要加载那些没有加载过的层,所以启动容器所需要的时间也大大缩短了。
Dockerfile 编写技巧
Dockerfile 是一种用于自动化构建 Docker 镜像的工具。在编写 Dockerfile 时,需要注意以下几点:
- 在选择基础镜像时,需要结合实际情况选择尽量轻量的镜像,以减少镜像的体积。
- 需要合理利用 Dockerfile 中的缓存机制。在 Dockerfile 的每一行指令中,都可以指定一个标签,当这个标签变化时,Docker 就会重新运行这一行指令及其后面的指令,因此,尽量使这些标签的修改频率尽可能的低。
- 合理使用多行语句和 .dockerignore 文件,以最大程度地减小镜像的体积。
下面是一个 Dockerfile 的示例,其中包含了以上所述的优化策略:
# 选择一个轻量的基础镜像
FROM alpine:3.14
# 向容器内添加文件
ADD index.js /app/
ADD package.json /app/
# 安装依赖
RUN apk add --no-cache nodejs npm \
&& cd /app \
&& npm install
# 暴露端口
EXPOSE 8080
# 指定容器启动时执行的命令
CMD ["node", "/app/index.js"]
通过多行语句,尽量减少了每个镜像层的数量。同时,在添加文件时使用了 .dockerignore 文件来排除掉一些不需要的文件,进一步减小了镜像的体积。
示例1:使用 Dockerfile 构建一个简单的 Node.js 服务器镜像
下面是一个构建 Node.js 服务器镜像的示例:
- 首先,在本地新建一个名为 app 的文件夹。
$ mkdir app && cd app
- 在 app 文件夹中,新建一个名为 index.js 的文件,内容如下:
const http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8080);
console.log('Server running at http://localhost:8080/');
- 新建一个名为 package.json 的文件,内容如下:
{
"name": "docker-nodejs-app",
"version": "0.0.1",
"description": "A simple Node.js app for Docker",
"main": "index.js",
"dependencies": {
"express": "^4.16.2"
}
}
- 在 app 文件夹中,新建一个 Dockerfile 文件,内容如下:
# 选择一个轻量的基础镜像
FROM alpine:3.14
# 向容器内添加文件
ADD index.js /app/
ADD package.json /app/
# 安装依赖
RUN apk add --no-cache nodejs npm \
&& cd /app \
&& npm install
# 暴露端口
EXPOSE 8080
# 指定容器启动时执行的命令
CMD ["node", "/app/index.js"]
- 在 app 文件夹中,打开终端,执行以下命令,使用 Dockerfile 构建镜像(注意最后的 .):
$ docker build -t node-app .
- 构建完成后,执行以下命令查看镜像:
$ docker images
- 启动容器:
$ docker run -p 8080:8080 node-app
- 访问 http://localhost:8080/ ,如果输出 Hello World 表示访问成功。
示例2:使用 Dockerfile 构建一个 Nginx 反向代理镜像
下面是一个构建 Nginx 反向代理镜像的示例:
- 首先,在本地新建一个名为 nginx 且包含一个代理配置的文件的文件夹。
$ mkdir nginx && cd nginx
- 在 nginx 文件夹中,新建一个名为 proxy.conf 的文件,内容如下:
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://backend:3000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
- 在 nginx 文件夹中,新建一个 Dockerfile 文件,内容如下:
# 选择一个预装有 Nginx 的基础镜像
FROM nginx:1.21
# 将代理配置文件复制到容器内
COPY proxy.conf /etc/nginx/conf.d/
# 暴露端口
EXPOSE 8080
- 在 nginx 文件夹中,打开终端,执行以下命令,使用 Dockerfile 构建镜像(注意最后的 .):
$ docker build -t nginx-proxy .
- 构建完成后,执行以下命令查看镜像:
$ docker images
- 启动一个 Node.js 服务器容器,容器名为 backend:
$ docker run -d --name backend node:latest
- 启动 Nginx 反向代理容器:
$ docker run -d --name nginx-proxy -p 8080:8080 --link backend nginx-proxy
- 访问 http://localhost:8080/ ,如果成功访问到了一个 Node.js 服务器,说明 Nginx 反向代理容器配置成功。
这两个示例分别说明了 Dockerfile 的编写和镜像层的分层存储,相信大家已经对这两个问题有了深入的了解。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Docker 镜像分层及dockerfile 编写技巧 - Python技术站